Skip to content

Commit c2e2aa1

Browse files
committed
Set RSA key size and label
Signed-off-by: Marcel Guzik <marcel.guzik@cumulocity.com>
1 parent 5d812d4 commit c2e2aa1

File tree

8 files changed

+89
-19
lines changed

8 files changed

+89
-19
lines changed

crates/core/tedge/src/cli/certificate/cli.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,13 @@ pub enum TEdgeCertCli {
5151
},
5252

5353
/// Create a new keypair
54-
CreateKey,
54+
CreateKey {
55+
#[arg(long, default_value = "2048")]
56+
bits: u16,
57+
58+
#[arg(long)]
59+
label: String,
60+
},
5561

5662
/// Renew the device certificate
5763
///
@@ -204,7 +210,7 @@ impl BuildCommand for TEdgeCertCli {
204210
cmd.into_boxed()
205211
}
206212

207-
TEdgeCertCli::CreateKey => CreateKeyCmd.into_boxed(),
213+
TEdgeCertCli::CreateKey { bits, label } => CreateKeyCmd { bits, label }.into_boxed(),
208214

209215
TEdgeCertCli::Show {
210216
cloud,

crates/core/tedge/src/cli/certificate/create_key.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
use tedge_config::TEdgeConfig;
2+
use tedge_p11_server::pkcs11::{CreateKeyParams, KeyTypeParams};
23

34
use crate::command::Command;
45
use crate::log::MaybeFancy;
56

6-
pub struct CreateKeyCmd;
7+
pub struct CreateKeyCmd {
8+
pub bits: u16,
9+
pub label: String,
10+
}
711

812
#[async_trait::async_trait]
913
impl Command for CreateKeyCmd {
@@ -16,7 +20,12 @@ impl Command for CreateKeyCmd {
1620
let pkcs11client = tedge_p11_server::client::TedgeP11Client::with_ready_check(
1721
socket_path.as_std_path().into(),
1822
);
19-
pkcs11client.create_key(None)?;
23+
let params = CreateKeyParams {
24+
key: KeyTypeParams::Rsa { bits: self.bits },
25+
token: None,
26+
label: self.label.clone(),
27+
};
28+
pkcs11client.create_key(None, params)?;
2029
eprintln!("New keypair was successfully created.");
2130
Ok(())
2231
}

crates/extensions/tedge-p11-server/src/client.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ use anyhow::Context;
77
use tracing::debug;
88
use tracing::trace;
99

10+
use crate::pkcs11::CreateKeyParams;
11+
use crate::service::CreateKeyRequest;
12+
1013
use super::connection::Frame1;
1114
use super::service::ChooseSchemeRequest;
1215
use super::service::SignRequest;
@@ -111,7 +114,7 @@ impl TedgeP11Client {
111114
Ok(response.0)
112115
}
113116

114-
pub fn create_key(&self, uri: Option<String>) -> anyhow::Result<()> {
117+
pub fn create_key(&self, uri: Option<String>, params: CreateKeyParams) -> anyhow::Result<()> {
115118
let stream = UnixStream::connect(&self.socket_path).with_context(|| {
116119
format!(
117120
"Failed to connect to tedge-p11-server UNIX socket at '{}'",
@@ -121,7 +124,7 @@ impl TedgeP11Client {
121124
let mut connection = crate::connection::Connection::new(stream);
122125
debug!("Connected to socket");
123126

124-
let request = Frame1::CreateKeyRequest(uri);
127+
let request = Frame1::CreateKeyRequest(CreateKeyRequest { uri, params });
125128
trace!(?request);
126129
connection.write_frame(&request)?;
127130

crates/extensions/tedge-p11-server/src/connection.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use tracing::warn;
1515

1616
use crate::service::ChooseSchemeRequest;
1717
use crate::service::ChooseSchemeResponse;
18+
use crate::service::CreateKeyRequest;
1819
use crate::service::SignRequest;
1920
use crate::service::SignResponse;
2021

@@ -89,7 +90,7 @@ pub enum Frame1 {
8990
SignRequest(SignRequest),
9091
ChooseSchemeResponse(ChooseSchemeResponse),
9192
SignResponse(SignResponse),
92-
CreateKeyRequest(Option<String>),
93+
CreateKeyRequest(CreateKeyRequest),
9394
CreateKeyResponse,
9495
}
9596

crates/extensions/tedge-p11-server/src/pkcs11/mod.rs

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ use rustls::sign::Signer;
2828
use rustls::sign::SigningKey;
2929
use rustls::SignatureAlgorithm;
3030
use rustls::SignatureScheme;
31+
use serde::Deserialize;
32+
use serde::Serialize;
3133
use tracing::debug;
3234
use tracing::trace;
3335
use tracing::warn;
@@ -189,11 +191,11 @@ impl Cryptoki {
189191
Ok(key)
190192
}
191193

192-
pub fn create_key(&self, uri: Option<&str>) -> anyhow::Result<()> {
194+
pub fn create_key(&self, uri: Option<&str>, params: CreateKeyParams) -> anyhow::Result<()> {
193195
let uri_attributes = self.request_uri(uri)?;
194196
let session = self.open_session(&uri_attributes)?;
195197

196-
create_key(&session).context("Failed to create a new private key")?;
198+
create_key(&session, params).context("Failed to create a new private key")?;
197199

198200
Ok(())
199201
}
@@ -251,28 +253,53 @@ impl Cryptoki {
251253
}
252254
}
253255

254-
fn create_key(session: &Session) -> anyhow::Result<()> {
256+
fn create_key(session: &Session, params: CreateKeyParams) -> anyhow::Result<()> {
257+
let KeyTypeParams::Rsa { bits } = params.key;
258+
anyhow::ensure!(
259+
bits == 2048 || bits == 3072 || bits == 4096,
260+
"Invalid bits value: only 2048/3072/4096 key sizes are valid"
261+
);
262+
263+
trace!(bits, "Generating keypair");
255264
session
256265
.generate_key_pair(
257266
&Mechanism::RsaPkcsKeyPairGen,
258267
&[
259-
Attribute::Token(true),
268+
// Attribute::Token(true),
269+
Attribute::Private(false),
260270
Attribute::Verify(true),
261271
Attribute::Encrypt(true),
262-
Attribute::ModulusBits(2048.into()),
272+
Attribute::ModulusBits(u64::from(bits).into()),
273+
// Attribute::Label("rsa_public".into()),
263274
],
264275
&[
265276
Attribute::Token(true),
277+
Attribute::Private(true),
266278
Attribute::Sensitive(true),
267279
Attribute::Extractable(false),
268280
Attribute::Sign(true),
269281
Attribute::Decrypt(true),
282+
Attribute::Label(params.label.into()),
283+
// Attribute::ModulusBits(u64::from(bits).into()),
284+
// Attribute::KeyType(KeyType::RSA),
270285
],
271286
)
272287
.context("Failed to generate keypair")?;
273288
Ok(())
274289
}
275290

291+
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
292+
pub struct CreateKeyParams {
293+
pub key: KeyTypeParams,
294+
pub token: Option<String>,
295+
pub label: String,
296+
}
297+
298+
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
299+
pub enum KeyTypeParams {
300+
Rsa { bits: u16 },
301+
}
302+
276303
#[derive(Debug, Clone)]
277304
pub struct Pkcs11SigningKey {
278305
session: PKCS11,

crates/extensions/tedge-p11-server/src/server.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,10 @@ impl TedgeP11Server {
8383
}
8484
}
8585
}
86-
Frame1::CreateKeyRequest(uri) => {
87-
let response = self.service.create_key(uri.as_deref());
86+
Frame1::CreateKeyRequest(request) => {
87+
let response = self
88+
.service
89+
.create_key(request.uri.as_deref(), request.params);
8890
match response {
8991
Ok(_) => Frame1::CreateKeyResponse,
9092
Err(err) => {
@@ -107,6 +109,7 @@ impl TedgeP11Server {
107109
#[cfg(test)]
108110
mod tests {
109111
use crate::client::TedgeP11Client;
112+
use crate::pkcs11::CreateKeyParams;
110113
use crate::service::*;
111114
use std::io::Read;
112115
use std::os::unix::net::UnixStream;
@@ -134,7 +137,7 @@ mod tests {
134137
Ok(SignResponse(SIGNATURE.to_vec()))
135138
}
136139

137-
fn create_key(&self, _uri: Option<&str>) -> anyhow::Result<()> {
140+
fn create_key(&self, _uri: Option<&str>, _params: CreateKeyParams) -> anyhow::Result<()> {
138141
todo!()
139142
}
140143
}

crates/extensions/tedge-p11-server/src/service.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::pkcs11::CreateKeyParams;
12
use crate::pkcs11::Cryptoki;
23
use crate::pkcs11::CryptokiConfigDirect;
34
use crate::pkcs11::PkcsSigner;
@@ -13,7 +14,7 @@ use tracing::warn;
1314
pub trait SigningService {
1415
fn choose_scheme(&self, request: ChooseSchemeRequest) -> anyhow::Result<ChooseSchemeResponse>;
1516
fn sign(&self, request: SignRequest) -> anyhow::Result<SignResponse>;
16-
fn create_key(&self, uri: Option<&str>) -> anyhow::Result<()>;
17+
fn create_key(&self, uri: Option<&str>, params: CreateKeyParams) -> anyhow::Result<()>;
1718
}
1819

1920
#[derive(Debug)]
@@ -79,8 +80,9 @@ impl SigningService for TedgeP11Service {
7980
Ok(SignResponse(signature))
8081
}
8182

82-
fn create_key(&self, uri: Option<&str>) -> anyhow::Result<()> {
83-
self.cryptoki.create_key(uri)?;
83+
#[instrument(skip_all)]
84+
fn create_key(&self, uri: Option<&str>, params: CreateKeyParams) -> anyhow::Result<()> {
85+
self.cryptoki.create_key(uri, params)?;
8486
Ok(())
8587
}
8688
}
@@ -106,6 +108,12 @@ pub struct SignRequest {
106108
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
107109
pub struct SignResponse(pub Vec<u8>);
108110

111+
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
112+
pub struct CreateKeyRequest {
113+
pub uri: Option<String>,
114+
pub params: CreateKeyParams,
115+
}
116+
109117
#[derive(Debug, Clone, PartialEq, Eq)]
110118
pub struct SignatureScheme(pub rustls::SignatureScheme);
111119

tests/RobotFramework/tests/pkcs11/private_key_storage.robot

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,24 @@ Creates a private key on the PKCS11 token
111111
Should Be Equal ${output} No matching objects found
112112

113113
Set tedge-p11-server Uri value=pkcs11:token=create-key-token
114-
Execute Command tedge cert create-key
115114

115+
Execute Command tedge cert create-key --label rsa-2048
116116
${output}= Execute Command
117117
... cmd=p11tool --login --set-pin=123456 --list-privkeys "pkcs11:token=create-key-token"
118118
Should Contain ${output} Object 0:
119+
Should Contain ${output} Type: Private key (RSA-2048)\n\tLabel: rsa-2048
120+
121+
Execute Command tedge cert create-key --label rsa-3072 --bits 3072
122+
${output}= Execute Command
123+
... cmd=p11tool --login --set-pin=123456 --list-privkeys "pkcs11:token=create-key-token"
124+
Should Contain ${output} Object 1:
125+
Should Contain ${output} Type: Private key (RSA-3072)\n\tLabel: rsa-3072
126+
127+
Execute Command tedge cert create-key --label rsa-4096 --bits 4096
128+
${output}= Execute Command
129+
... cmd=p11tool --login --set-pin=123456 --list-privkeys "pkcs11:token=create-key-token"
130+
Should Contain ${output} Object 2:
131+
Should Contain ${output} Type: Private key (RSA-4096)\n\tLabel: rsa-4096
119132

120133
[Teardown] Set tedge-p11-server Uri value=
121134

0 commit comments

Comments
 (0)