1use crate::{
2 raw::{self, CRYPTO_ERRNO_UNSUPPORTED_ALGORITHM},
3 CryptoErrno, NONE_OPTS,
4};
5use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine};
6
7#[derive(Clone, Copy, PartialEq, Eq)]
9pub enum KeyEncodingFormat {
10 Pem,
11 Der,
12 Jwk,
14}
15
16#[derive(Clone, Copy, PartialEq, Eq)]
17pub(crate) enum CurveKind {
18 Prime256v1,
19 Secp256k1,
20 Secp384r1,
21}
22
23const OID_CURVE_PRIME256V1: &str = "1.2.840.10045.3.1.7";
24const OID_CURVE_SECP256K1: &str = "1.3.132.0.10";
25const OID_CURVE_SECP384R1: &str = "1.3.132.0.34";
26const OID_ED25519: &str = "1.3.101.112";
27const OID_X25519: &str = "1.3.101.110";
28
29#[derive(Clone, Copy, PartialEq, Eq)]
30pub(crate) enum DigestKind {
31 SHA256,
32 SHA384,
33 SHA512,
34}
35
36#[derive(Clone, Copy, PartialEq, Eq)]
56pub(crate) enum AlgoKind {
57 Ed,
58 Ec(CurveKind),
59 Rsa(i32, DigestKind),
60 RsaPss(i32, DigestKind),
61 X25519,
62}
63
64impl AlgoKind {
65 fn from_str(algo: &str) -> Result<Self, CryptoErrno> {
66 let algo = algo.to_uppercase();
67 let mut iter = algo.split('_');
68 let a = iter.next();
69 let b = iter.next();
70 let c = iter.next();
71 let d = iter.next();
72 match (a, b, c, d) {
73 (Some("ED25519"), _, _, _) => Ok(AlgoKind::Ed),
74 (Some("X25519"), _, _, _) => Ok(AlgoKind::X25519),
75 (Some("ECDSA"), Some("P256"), _, _) => Ok(AlgoKind::Ec(CurveKind::Prime256v1)),
76 (Some("ECDSA"), Some("K256"), _, _) => Ok(AlgoKind::Ec(CurveKind::Secp256k1)),
77 (Some("ECDSA"), Some("P384"), _, _) => Ok(AlgoKind::Ec(CurveKind::Secp384r1)),
78 (Some("RSA"), Some("PKCS1"), Some("2048"), None | Some("SHA256")) => {
79 Ok(AlgoKind::Rsa(2048, DigestKind::SHA256))
80 }
81 (Some("RSA"), Some("PKCS1"), Some("2048"), Some("SHA384")) => {
82 Ok(AlgoKind::Rsa(2048, DigestKind::SHA384))
83 }
84 (Some("RSA"), Some("PKCS1"), Some("2048"), Some("SHA512")) => {
85 Ok(AlgoKind::Rsa(2048, DigestKind::SHA512))
86 }
87 (Some("RSA"), Some("PKCS1"), Some("3072"), None | Some("SHA384")) => {
88 Ok(AlgoKind::Rsa(3072, DigestKind::SHA384))
89 }
90 (Some("RSA"), Some("PKCS1"), Some("3072"), Some("SHA512")) => {
91 Ok(AlgoKind::Rsa(3072, DigestKind::SHA512))
92 }
93 (Some("RSA"), Some("PKCS1"), Some("4096"), None | Some("SHA512")) => {
94 Ok(AlgoKind::Rsa(4096, DigestKind::SHA512))
95 }
96 (Some("RSA"), Some("PSS"), Some("2048"), None | Some("SHA256")) => {
97 Ok(AlgoKind::RsaPss(2048, DigestKind::SHA256))
98 }
99 (Some("RSA"), Some("PSS"), Some("2048"), Some("SHA384")) => {
100 Ok(AlgoKind::RsaPss(2048, DigestKind::SHA384))
101 }
102 (Some("RSA"), Some("PSS"), Some("2048"), Some("SHA512")) => {
103 Ok(AlgoKind::RsaPss(2048, DigestKind::SHA512))
104 }
105 (Some("RSA"), Some("PSS"), Some("3072"), None | Some("SHA384")) => {
106 Ok(AlgoKind::RsaPss(3072, DigestKind::SHA384))
107 }
108 (Some("RSA"), Some("PSS"), Some("3072"), Some("SHA512")) => {
109 Ok(AlgoKind::RsaPss(3072, DigestKind::SHA512))
110 }
111 (Some("RSA"), Some("PSS"), Some("4096"), None | Some("SHA512")) => {
112 Ok(AlgoKind::RsaPss(4096, DigestKind::SHA512))
113 }
114 _ => Err(raw::CRYPTO_ERRNO_UNSUPPORTED_ALGORITHM),
115 }
116 }
117
118 pub(crate) fn to_str(&self) -> &'static str {
119 match self {
120 AlgoKind::Ed => "ED25519",
121 AlgoKind::X25519 => "X25519",
122 AlgoKind::Ec(curve) => match curve {
123 CurveKind::Prime256v1 => "ECDSA_P256_SHA256",
124 CurveKind::Secp256k1 => "ECDSA_K256_SHA256",
125 CurveKind::Secp384r1 => "ECDSA_P384_SHA384",
126 },
127 AlgoKind::Rsa(len, digest) => match len {
128 2048 => match digest {
129 DigestKind::SHA256 => "RSA_PKCS1_2048_SHA256",
130 DigestKind::SHA384 => "RSA_PKCS1_2048_SHA384",
131 DigestKind::SHA512 => "RSA_PKCS1_2048_SHA512",
132 },
133 3072 => match digest {
134 DigestKind::SHA384 => "RSA_PKCS1_3072_SHA384",
135 DigestKind::SHA512 => "RSA_PKCS1_3072_SHA512",
136 _ => unreachable!(),
137 },
138 4096 => match digest {
139 DigestKind::SHA512 => "RSA_PKCS1_4096_SHA512",
140 _ => unreachable!(),
141 },
142 _ => unreachable!(),
143 },
144 AlgoKind::RsaPss(len, digest) => match len {
145 2048 => match digest {
146 DigestKind::SHA256 => "RSA_PSS_2048_SHA256",
147 DigestKind::SHA384 => "RSA_PSS_2048_SHA384",
148 DigestKind::SHA512 => "RSA_PSS_2048_SHA512",
149 },
150 3072 => match digest {
151 DigestKind::SHA384 => "RSA_PSS_3072_SHA384",
152 DigestKind::SHA512 => "RSA_PSS_3072_SHA512",
153 _ => unreachable!(),
154 },
155 4096 => match digest {
156 DigestKind::SHA512 => "RSA_PSS_4096_SHA512",
157 _ => unreachable!(),
158 },
159 _ => unreachable!(),
160 },
161 }
162 }
163}
164
165pub struct PublicKey {
167 pub(crate) handle: raw::Publickey,
168 pub(crate) algo: AlgoKind,
169}
170
171#[derive(Clone, Copy, PartialEq, Eq)]
173pub enum PublicKeyEncodingType {
174 Spki,
175 Pkcs1,
176}
177
178fn publickey_export(
179 pk: raw::Publickey,
180 encoding: raw::PublickeyEncoding,
181) -> Result<Vec<u8>, CryptoErrno> {
182 let res = unsafe {
183 let arr = raw::publickey_export(pk, encoding)?;
184 let len = raw::array_output_len(arr)?;
185 let mut buf = vec![0; len];
186 raw::array_output_pull(arr, buf.as_mut_ptr(), buf.len())?;
187 buf
188 };
189 Ok(res)
190}
191
192fn secretkey_export(
193 sk: raw::Secretkey,
194 encoding: raw::SecretkeyEncoding,
195) -> Result<Vec<u8>, CryptoErrno> {
196 let res = unsafe {
197 let arr = raw::secretkey_export(sk, encoding)?;
198 let len = raw::array_output_len(arr)?;
199 let mut buf = vec![0; len];
200 raw::array_output_pull(arr, buf.as_mut_ptr(), buf.len())?;
201 buf
202 };
203 Ok(res)
204}
205
206impl PublicKey {
207 pub fn export(
208 &self,
209 kind: PublicKeyEncodingType,
210 format: KeyEncodingFormat,
211 ) -> Result<Vec<u8>, CryptoErrno> {
212 match (self.algo, kind, format) {
216 (AlgoKind::Rsa(_, _), PublicKeyEncodingType::Spki, KeyEncodingFormat::Pem)
217 | (AlgoKind::RsaPss(_, _), PublicKeyEncodingType::Spki, KeyEncodingFormat::Pem)
218 | (AlgoKind::Ec(_), PublicKeyEncodingType::Spki, KeyEncodingFormat::Pem) => {
219 publickey_export(self.handle, raw::PUBLICKEY_ENCODING_PEM)
220 }
221 (AlgoKind::Rsa(_, _), PublicKeyEncodingType::Spki, KeyEncodingFormat::Der)
222 | (AlgoKind::RsaPss(_, _), PublicKeyEncodingType::Spki, KeyEncodingFormat::Der)
223 | (AlgoKind::Ec(_), PublicKeyEncodingType::Spki, KeyEncodingFormat::Der) => {
224 publickey_export(self.handle, raw::PUBLICKEY_ENCODING_PKCS8)
225 }
226 (AlgoKind::Ec(curve), _, KeyEncodingFormat::Jwk) => {
227 let bin = publickey_export(self.handle, raw::PUBLICKEY_ENCODING_SEC)?;
228 let compress_kind = bin[0];
229 assert!(compress_kind == 0x04, "only support uncompressed form now");
231 let x = URL_SAFE_NO_PAD.encode(&bin[1..33]);
232 let y = URL_SAFE_NO_PAD.encode(&bin[33..65]);
233 let curve_name = match curve {
234 CurveKind::Prime256v1 => "P-256",
235 CurveKind::Secp256k1 => "secp256k1",
236 CurveKind::Secp384r1 => "P-384",
237 };
238 let jwk = format!(r#"{{"x":"{x}","y":"{y}","kty":"EC","crv":"{curve_name}"}}"#);
239 Ok(jwk.into_bytes())
240 }
241 (AlgoKind::Rsa(_, _), _, KeyEncodingFormat::Jwk) => {
242 let der = publickey_export(self.handle, raw::PUBLICKEY_ENCODING_PKCS8)?;
243 let raw = SubjectPublicKeyInfo::from_der(&der)
244 .unwrap()
245 .subject_public_key
246 .as_bytes()
247 .unwrap();
248 let rsa_pk = RsaPublicKey::from_der(raw).unwrap();
249 let n = URL_SAFE_NO_PAD.encode(rsa_pk.modulus.as_bytes());
250 let e = URL_SAFE_NO_PAD.encode(rsa_pk.public_exponent.as_bytes());
251 let jwk = format!(r#"{{"n":"{n}","e":"{e}","kty":"RSA"}}"#);
252 Ok(jwk.into_bytes())
253 }
254 (AlgoKind::RsaPss(_, _), _, KeyEncodingFormat::Jwk) => {
255 Err(raw::CRYPTO_ERRNO_UNSUPPORTED_ENCODING)
256 }
257 (AlgoKind::Ed, PublicKeyEncodingType::Spki, KeyEncodingFormat::Der)
258 | (AlgoKind::Ed, PublicKeyEncodingType::Spki, KeyEncodingFormat::Pem) => {
259 let raw = publickey_export(self.handle, raw::PUBLICKEY_ENCODING_RAW)?;
260 let spki = SubjectPublicKeyInfo {
261 algorithm: AlgorithmIdentifier {
262 algorithm: ObjectIdentifier::new(OID_ED25519).unwrap(),
263 parameters: None,
264 },
265 subject_public_key: BitStringRef::new(0, &raw).unwrap(),
266 };
267 let der = spki.to_der().unwrap();
268 match format {
269 KeyEncodingFormat::Der => Ok(der),
270 KeyEncodingFormat::Pem => Ok(pem::encode(&pem::Pem {
271 tag: "PUBLIC KEY".to_string(),
272 contents: der,
273 })
274 .into_bytes()),
275 KeyEncodingFormat::Jwk => unreachable!(),
276 }
277 }
278 (AlgoKind::Ed, _, KeyEncodingFormat::Jwk) => {
279 let raw = publickey_export(self.handle, raw::PUBLICKEY_ENCODING_RAW)?;
280 let x = URL_SAFE_NO_PAD.encode(raw);
281 let jwk = format!(r#"{{"crv":"Ed25519","x":"{x}","kty":"OKP"}}"#);
282 Ok(jwk.into_bytes())
283 }
284 (AlgoKind::Rsa(_, _), PublicKeyEncodingType::Pkcs1, KeyEncodingFormat::Pem)
285 | (AlgoKind::Rsa(_, _), PublicKeyEncodingType::Pkcs1, KeyEncodingFormat::Der) => {
286 let der = publickey_export(self.handle, raw::PUBLICKEY_ENCODING_PKCS8)?;
287 let rsa_pk = SubjectPublicKeyInfo::from_der(&der)
288 .unwrap()
289 .subject_public_key
290 .as_bytes()
291 .unwrap();
292 match format {
293 KeyEncodingFormat::Jwk => unreachable!(),
294 KeyEncodingFormat::Der => Ok(rsa_pk.to_vec()),
295 KeyEncodingFormat::Pem => Ok(pem::encode(&pem::Pem {
296 tag: "RSA PUBLIC KEY".to_string(),
297 contents: rsa_pk.to_vec(),
298 })
299 .into_bytes()),
300 }
301 }
302 (_, PublicKeyEncodingType::Pkcs1, _) => Err(raw::CRYPTO_ERRNO_UNSUPPORTED_ENCODING),
303 (AlgoKind::X25519, PublicKeyEncodingType::Spki, KeyEncodingFormat::Pem)
304 | (AlgoKind::X25519, PublicKeyEncodingType::Spki, KeyEncodingFormat::Der) => {
305 let raw = publickey_export(self.handle, raw::PUBLICKEY_ENCODING_RAW)?;
306 let skpi = SubjectPublicKeyInfo {
307 algorithm: AlgorithmIdentifier {
308 algorithm: ObjectIdentifier::new(OID_X25519).unwrap(),
309 parameters: None,
310 },
311 subject_public_key: BitStringRef::new(0, &raw).unwrap(),
312 };
313 let der = skpi.to_der().unwrap();
314 if format == KeyEncodingFormat::Der {
315 Ok(der)
316 } else {
317 Ok(pem::encode(&pem::Pem {
318 tag: "PUBLIC KEY".to_string(),
319 contents: der,
320 })
321 .into_bytes())
322 }
323 }
324 (AlgoKind::X25519, PublicKeyEncodingType::Spki, KeyEncodingFormat::Jwk) => {
325 let raw = publickey_export(self.handle, raw::PUBLICKEY_ENCODING_RAW)?;
326 let x = URL_SAFE_NO_PAD.encode(raw);
327 let jwk = format!(r#"{{"crv":"X25519","x":"{x}","kty":"OKP"}}"#);
328 Ok(jwk.into_bytes())
329 }
330 }
331 }
332
333 pub(crate) fn cast_to_dh_key(&self) -> Result<PublicKey, CryptoErrno> {
334 match self.algo {
335 AlgoKind::Ec(CurveKind::Prime256v1) | AlgoKind::Ec(CurveKind::Secp384r1) => unsafe {
336 let raw = publickey_export(self.handle, raw::PUBLICKEY_ENCODING_PEM)?;
337 let pk = raw::publickey_import(
338 raw::ALGORITHM_TYPE_KEY_EXCHANGE,
339 if self.algo == AlgoKind::Ec(CurveKind::Prime256v1) {
340 "P256-SHA256"
341 } else {
342 "P384-SHA384"
343 },
344 raw.as_ptr(),
345 raw.len(),
346 raw::PUBLICKEY_ENCODING_PEM,
347 )?;
348 Ok(PublicKey {
349 handle: pk,
350 algo: self.algo,
351 })
352 },
353 _ => Err(CRYPTO_ERRNO_UNSUPPORTED_ALGORITHM),
354 }
355 }
356}
357
358pub struct PrivateKey {
360 pub(crate) handle: raw::Secretkey,
361 pub(crate) keypair_handle: raw::Keypair,
363 pub(crate) algo: AlgoKind,
364}
365
366#[derive(Clone, Copy, PartialEq, Eq)]
368pub enum PrivateKeyEncodingType {
369 Pkcs8,
370 Pkcs1,
371 Sec1,
372}
373
374impl PrivateKey {
375 fn get_publickey(&self) -> Result<PublicKey, CryptoErrno> {
376 let pk = unsafe { raw::keypair_publickey(self.keypair_handle) }?;
378 Ok(PublicKey {
379 handle: pk,
380 algo: self.algo,
381 })
382 }
383
384 pub fn export(
385 &self,
386 kind: PrivateKeyEncodingType,
387 format: KeyEncodingFormat,
388 ) -> Result<Vec<u8>, CryptoErrno> {
389 match (self.algo, kind, format) {
393 (AlgoKind::Ec(_), PrivateKeyEncodingType::Pkcs8, KeyEncodingFormat::Pem)
394 | (AlgoKind::Rsa(_, _), PrivateKeyEncodingType::Pkcs8, KeyEncodingFormat::Pem)
395 | (AlgoKind::RsaPss(_, _), PrivateKeyEncodingType::Pkcs8, KeyEncodingFormat::Pem) => {
396 secretkey_export(self.handle, raw::SECRETKEY_ENCODING_PEM)
397 }
398 (AlgoKind::Ec(_), PrivateKeyEncodingType::Pkcs8, KeyEncodingFormat::Der)
399 | (AlgoKind::RsaPss(_, _), PrivateKeyEncodingType::Pkcs8, KeyEncodingFormat::Der) => {
400 secretkey_export(self.handle, raw::SECRETKEY_ENCODING_PKCS8)
401 }
402 (AlgoKind::Rsa(_, _), PrivateKeyEncodingType::Pkcs8, KeyEncodingFormat::Der) => {
403 let pkcs8 = secretkey_export(self.handle, raw::SECRETKEY_ENCODING_PEM)?;
404 pem::parse(pkcs8)
405 .map(|p| p.contents)
406 .or(Err(raw::CRYPTO_ERRNO_ALGORITHM_FAILURE))
407 }
408 (AlgoKind::Ed, PrivateKeyEncodingType::Pkcs8, KeyEncodingFormat::Pem)
409 | (AlgoKind::Ed, PrivateKeyEncodingType::Pkcs8, KeyEncodingFormat::Der)
410 | (AlgoKind::X25519, PrivateKeyEncodingType::Pkcs8, KeyEncodingFormat::Pem)
411 | (AlgoKind::X25519, PrivateKeyEncodingType::Pkcs8, KeyEncodingFormat::Der) => {
412 let raw = secretkey_export(self.handle, raw::SECRETKEY_ENCODING_RAW)?;
413 let der = PrivateKeyInfo::new(
414 AlgorithmIdentifier {
415 algorithm: ObjectIdentifier::new(if self.algo == AlgoKind::Ed {
416 OID_ED25519
417 } else {
418 OID_X25519
419 })
420 .unwrap(),
421 parameters: None,
422 },
423 &OctetString::new(raw).unwrap().to_der().unwrap(),
424 )
425 .to_der()
426 .unwrap();
427 match format {
428 KeyEncodingFormat::Der => Ok(der),
429 KeyEncodingFormat::Pem => Ok(pem::encode(&pem::Pem {
430 tag: "PRIVATE KEY".to_string(),
431 contents: der,
432 })
433 .into_bytes()),
434 KeyEncodingFormat::Jwk => unreachable!(),
435 }
436 }
437 (AlgoKind::Rsa(_, _), PrivateKeyEncodingType::Pkcs1, KeyEncodingFormat::Pem)
438 | (AlgoKind::Rsa(_, _), PrivateKeyEncodingType::Pkcs1, KeyEncodingFormat::Der) => {
439 let pkcs8 = self.export(PrivateKeyEncodingType::Pkcs8, KeyEncodingFormat::Der)?;
440 let raw = PrivateKeyInfo::from_der(&pkcs8).unwrap().private_key;
441 match format {
442 KeyEncodingFormat::Der => Ok(raw.to_vec()),
443 KeyEncodingFormat::Pem => Ok(pem::encode(&pem::Pem {
444 tag: "RSA PRIVATE KEY".to_string(),
445 contents: raw.to_vec(),
446 })
447 .into_bytes()),
448 KeyEncodingFormat::Jwk => unreachable!(),
449 }
450 }
451 (AlgoKind::Ec(curve), PrivateKeyEncodingType::Sec1, KeyEncodingFormat::Pem)
452 | (AlgoKind::Ec(curve), PrivateKeyEncodingType::Sec1, KeyEncodingFormat::Der) => {
453 let res = secretkey_export(self.handle, raw::SECRETKEY_ENCODING_RAW)?;
454 let curve = match curve {
455 CurveKind::Prime256v1 => OID_CURVE_PRIME256V1,
456 CurveKind::Secp256k1 => OID_CURVE_SECP256K1,
457 CurveKind::Secp384r1 => OID_CURVE_SECP384R1,
458 };
459 let pk = self.get_publickey()?;
460 let pk_data = publickey_export(pk.handle, raw::PUBLICKEY_ENCODING_SEC)?;
462 let sec1 = EcPrivateKey {
463 private_key: &res,
464 parameters: Some(EcParameters::NamedCurve(curve.parse().unwrap())),
465 public_key: Some(&pk_data),
466 };
467 let der = sec1.to_der().unwrap();
468 match format {
469 KeyEncodingFormat::Pem => Ok(pem::encode(&pem::Pem {
470 tag: "EC PRIVATE KEY".to_string(),
471 contents: der,
472 })
473 .into_bytes()),
474 KeyEncodingFormat::Der => Ok(der),
475 KeyEncodingFormat::Jwk => unreachable!(),
476 }
477 }
478 (AlgoKind::Ed, _, KeyEncodingFormat::Jwk)
479 | (AlgoKind::X25519, _, KeyEncodingFormat::Jwk) => {
480 let raw = secretkey_export(self.handle, raw::SECRETKEY_ENCODING_RAW)?;
481 let d = URL_SAFE_NO_PAD.encode(raw);
482 let pk = self.get_publickey()?;
483 let pkraw = publickey_export(pk.handle, raw::PUBLICKEY_ENCODING_RAW)?;
484 let x = URL_SAFE_NO_PAD.encode(pkraw);
485 let jwk = format!(
486 r#"{{"crv":"{}","d":"{d}","x":"{x}","kty":"OKP"}}"#,
487 if self.algo == AlgoKind::X25519 {
488 "X25519"
489 } else {
490 "Ed25519"
491 }
492 );
493 Ok(jwk.into_bytes())
494 }
495 (AlgoKind::Ec(curve), _, KeyEncodingFormat::Jwk) => {
496 let bins = secretkey_export(self.handle, raw::SECRETKEY_ENCODING_RAW)?;
497 let curve_name = match curve {
498 CurveKind::Prime256v1 => "P-256",
499 CurveKind::Secp256k1 => "secp256k1",
500 CurveKind::Secp384r1 => "P-384",
501 };
502 let pk = self.get_publickey()?;
503 let binp = publickey_export(pk.handle, raw::PUBLICKEY_ENCODING_SEC)?;
504 let compress_kind = binp[0];
505 if compress_kind != 0x04 {
508 Err(raw::CRYPTO_ERRNO_NOT_IMPLEMENTED)
509 } else {
510 let d = URL_SAFE_NO_PAD.encode(bins);
511 let x = URL_SAFE_NO_PAD.encode(&binp[1..33]);
512 let y = URL_SAFE_NO_PAD.encode(&binp[33..65]);
513 let jwk = format!(
514 r#"{{"x":"{x}","y":"{y}","kty":"EC","crv":"{curve_name}","d":"{d}"}}"#
515 );
516 Ok(jwk.into_bytes())
517 }
518 }
519 (AlgoKind::Rsa(_, _), _, KeyEncodingFormat::Jwk) => {
520 let pkcs1 = self.export(PrivateKeyEncodingType::Pkcs1, KeyEncodingFormat::Der)?;
521 let raw = RsaPrivateKey::from_der(&pkcs1).unwrap();
522 let n = URL_SAFE_NO_PAD.encode(raw.modulus.as_bytes());
523 let e = URL_SAFE_NO_PAD.encode(raw.public_exponent.as_bytes());
524 let d = URL_SAFE_NO_PAD.encode(raw.private_exponent.as_bytes());
525 let p = URL_SAFE_NO_PAD.encode(raw.prime1.as_bytes());
526 let q = URL_SAFE_NO_PAD.encode(raw.prime2.as_bytes());
527 let dp = URL_SAFE_NO_PAD.encode(raw.exponent1.as_bytes());
528 let dq = URL_SAFE_NO_PAD.encode(raw.exponent2.as_bytes());
529 let qi = URL_SAFE_NO_PAD.encode(raw.coefficient.as_bytes());
530 let jwk = format!(
531 r#"{{"n":"{n}","e":"{e}","kty":"RSA","d":"{d}","p":"{p}","q":"{q}","dp":"{dp}","dq":"{dq}","qi":"{qi}"}}"#
532 );
533 Ok(jwk.into_bytes())
534 }
535 (AlgoKind::Rsa(_, _), PrivateKeyEncodingType::Sec1, _)
536 | (AlgoKind::RsaPss(_, _), PrivateKeyEncodingType::Sec1, _)
537 | (AlgoKind::Ed, PrivateKeyEncodingType::Sec1, _)
538 | (AlgoKind::RsaPss(_, _), _, KeyEncodingFormat::Jwk)
539 | (AlgoKind::Ed, PrivateKeyEncodingType::Pkcs1, _)
540 | (AlgoKind::Ec(_), PrivateKeyEncodingType::Pkcs1, _)
541 | (AlgoKind::RsaPss(_, _), PrivateKeyEncodingType::Pkcs1, _)
542 | (AlgoKind::X25519, PrivateKeyEncodingType::Pkcs1 | PrivateKeyEncodingType::Sec1, _) => {
543 Err(raw::CRYPTO_ERRNO_UNSUPPORTED_ENCODING)
544 }
545 }
546 }
547
548 pub fn get_asymmetric_key_type(&self) -> &'static str {
549 match self.algo {
550 AlgoKind::Ed => "ed25519",
551 AlgoKind::Ec(_) => "ec",
552 AlgoKind::Rsa(_, _) => "rsa",
553 AlgoKind::RsaPss(_, _) => "rsa-pss",
554 AlgoKind::X25519 => "x25519",
555 }
556 }
557
558 pub(crate) fn cast_to_dh_key(&self) -> Result<PrivateKey, CryptoErrno> {
559 match self.algo {
560 AlgoKind::Ec(CurveKind::Prime256v1) | AlgoKind::Ec(CurveKind::Secp384r1) => unsafe {
561 let raw = secretkey_export(self.handle, raw::SECRETKEY_ENCODING_RAW)?;
562 let sk = raw::secretkey_import(
563 raw::ALGORITHM_TYPE_KEY_EXCHANGE,
564 if self.algo == AlgoKind::Ec(CurveKind::Prime256v1) {
565 "P256-SHA256"
566 } else {
567 "P384-SHA384"
568 },
569 raw.as_ptr(),
570 raw.len(),
571 raw::SECRETKEY_ENCODING_RAW,
572 )?;
573 Ok(PrivateKey {
575 handle: sk,
576 keypair_handle: 0,
577 algo: self.algo,
578 })
579 },
580 _ => Err(CRYPTO_ERRNO_UNSUPPORTED_ALGORITHM),
581 }
582 }
583}
584
585pub fn generate_key_pair(algorithm: &str) -> Result<(PublicKey, PrivateKey), CryptoErrno> {
608 let algo = AlgoKind::from_str(algorithm)?;
609 let (pk, sk, kp) = unsafe {
610 let kp = raw::keypair_generate(
611 if matches!(algo, AlgoKind::X25519) {
612 raw::ALGORITHM_TYPE_KEY_EXCHANGE
613 } else {
614 raw::ALGORITHM_TYPE_SIGNATURES
615 },
616 algorithm,
617 NONE_OPTS,
618 )?;
619 (raw::keypair_publickey(kp)?, raw::keypair_secretkey(kp)?, kp)
620 };
621 Ok((
622 PublicKey { handle: pk, algo },
623 PrivateKey {
624 handle: sk,
625 keypair_handle: kp,
626 algo,
627 },
628 ))
629}
630
631use der::{
660 asn1::{
661 AnyRef, BitStringRef, ContextSpecific, ContextSpecificRef, ObjectIdentifier, OctetString,
662 OctetStringRef, UintRef,
663 },
664 Decode, DecodeValue, Encode, EncodeValue, FixedTag, Header, Length, Reader, Sequence, Tag,
665 TagMode, TagNumber, Writer,
666};
667
668#[derive(Copy, Clone, Debug, Eq, PartialEq)]
670struct AlgorithmIdentifier<'a> {
671 pub algorithm: ObjectIdentifier,
673
674 pub parameters: Option<AnyRef<'a>>,
677}
678
679impl<'a> DecodeValue<'a> for AlgorithmIdentifier<'a> {
680 fn decode_value<R: Reader<'a>>(reader: &mut R, _header: Header) -> der::Result<Self> {
681 let algorithm = reader.decode()?;
695
696 let parameters = reader.decode()?;
702
703 Ok(Self {
708 algorithm,
709 parameters,
710 })
711 }
712}
713
714impl<'a> ::der::EncodeValue for AlgorithmIdentifier<'a> {
715 fn value_len(&self) -> ::der::Result<::der::Length> {
716 self.algorithm.encoded_len()? + self.parameters.encoded_len()?
717 }
718
719 fn encode_value(&self, writer: &mut impl ::der::Writer) -> ::der::Result<()> {
720 self.algorithm.encode(writer)?;
721 self.parameters.encode(writer)?;
722 Ok(())
723 }
724}
725
726impl<'a> Sequence<'a> for AlgorithmIdentifier<'a> {}
727
728#[derive(Copy, Clone, Debug, Eq, PartialEq)]
730struct SubjectPublicKeyInfo<'a> {
731 algorithm: AlgorithmIdentifier<'a>,
733
734 subject_public_key: BitStringRef<'a>,
736}
737
738impl<'a> DecodeValue<'a> for SubjectPublicKeyInfo<'a> {
739 fn decode_value<R: Reader<'a>>(reader: &mut R, _header: Header) -> der::Result<Self> {
740 let algorithm = reader.decode()?;
741 let subject_public_key = reader.decode()?;
742 Ok(Self {
743 algorithm,
744 subject_public_key,
745 })
746 }
747}
748
749impl<'a> EncodeValue for SubjectPublicKeyInfo<'a> {
750 fn value_len(&self) -> der::Result<Length> {
751 self.algorithm.encoded_len()? + self.subject_public_key.encoded_len()?
752 }
753
754 fn encode_value(&self, encoder: &mut impl Writer) -> der::Result<()> {
755 self.algorithm.encode(encoder)?;
756 self.subject_public_key.encode(encoder)
757 }
758}
759
760impl<'a> Sequence<'a> for SubjectPublicKeyInfo<'a> {}
761
762#[derive(Copy, Clone, Debug, Eq, PartialEq)]
777enum EcParameters {
778 NamedCurve(ObjectIdentifier),
784}
785
786impl<'a> DecodeValue<'a> for EcParameters {
787 fn decode_value<R: Reader<'a>>(decoder: &mut R, header: Header) -> der::Result<Self> {
788 ObjectIdentifier::decode_value(decoder, header).map(Self::NamedCurve)
789 }
790}
791
792impl FixedTag for EcParameters {
793 const TAG: Tag = Tag::ObjectIdentifier;
794}
795
796impl EncodeValue for EcParameters {
797 fn value_len(&self) -> der::Result<Length> {
798 match self {
799 Self::NamedCurve(oid) => oid.value_len(),
800 }
801 }
802
803 fn encode_value(&self, writer: &mut impl Writer) -> der::Result<()> {
804 match self {
805 Self::NamedCurve(oid) => oid.encode_value(writer),
806 }
807 }
808}
809
810#[derive(Clone)]
833struct EcPrivateKey<'a> {
834 private_key: &'a [u8],
836
837 parameters: Option<EcParameters>,
839
840 public_key: Option<&'a [u8]>,
842}
843
844const VERSION: u8 = 1;
854
855const EC_PARAMETERS_TAG: TagNumber = TagNumber::new(0);
857
858const PUBLIC_KEY_TAG: TagNumber = TagNumber::new(1);
860
861impl<'a> DecodeValue<'a> for EcPrivateKey<'a> {
862 fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> der::Result<Self> {
863 reader.read_nested(header.length, |reader| {
864 if u8::decode(reader)? != VERSION {
865 return Err(der::Tag::Integer.value_error());
866 }
867
868 let private_key = OctetStringRef::decode(reader)?.as_bytes();
869 let parameters = reader.context_specific(EC_PARAMETERS_TAG, TagMode::Explicit)?;
870 let public_key = reader
871 .context_specific::<BitStringRef<'_>>(PUBLIC_KEY_TAG, TagMode::Explicit)?
872 .map(|bs| bs.as_bytes().ok_or_else(|| Tag::BitString.value_error()))
873 .transpose()?;
874
875 Ok(EcPrivateKey {
876 private_key,
877 parameters,
878 public_key,
879 })
880 })
881 }
882}
883
884impl<'a> EcPrivateKey<'a> {
885 fn context_specific_parameters(&self) -> Option<ContextSpecificRef<'_, EcParameters>> {
886 self.parameters.as_ref().map(|params| ContextSpecificRef {
887 tag_number: EC_PARAMETERS_TAG,
888 tag_mode: TagMode::Explicit,
889 value: params,
890 })
891 }
892
893 fn context_specific_public_key(
894 &self,
895 ) -> der::Result<Option<ContextSpecific<BitStringRef<'a>>>> {
896 self.public_key
897 .map(|pk| {
898 BitStringRef::from_bytes(pk).map(|value| ContextSpecific {
899 tag_number: PUBLIC_KEY_TAG,
900 tag_mode: TagMode::Explicit,
901 value,
902 })
903 })
904 .transpose()
905 }
906}
907
908impl<'a> EncodeValue for EcPrivateKey<'a> {
909 fn value_len(&self) -> der::Result<Length> {
910 VERSION.encoded_len()?
911 + OctetStringRef::new(self.private_key)?.encoded_len()?
912 + self.context_specific_parameters().encoded_len()?
913 + self.context_specific_public_key()?.encoded_len()?
914 }
915
916 fn encode_value(&self, encoder: &mut impl Writer) -> der::Result<()> {
917 VERSION.encode(encoder)?;
918 OctetStringRef::new(self.private_key)?.encode(encoder)?;
919 self.context_specific_parameters().encode(encoder)?;
920 self.context_specific_public_key()?.encode(encoder)
921 }
922}
923
924impl<'a> Sequence<'a> for EcPrivateKey<'a> {}
925
926#[derive(Copy, Clone, Debug, Eq, PartialEq)]
939struct RsaPublicKey<'a> {
940 pub modulus: UintRef<'a>,
942
943 pub public_exponent: UintRef<'a>,
945}
946
947impl<'a> DecodeValue<'a> for RsaPublicKey<'a> {
948 fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> der::Result<Self> {
949 reader.read_nested(header.length, |reader| {
950 Ok(Self {
951 modulus: reader.decode()?,
952 public_exponent: reader.decode()?,
953 })
954 })
955 }
956}
957
958impl EncodeValue for RsaPublicKey<'_> {
959 fn value_len(&self) -> der::Result<Length> {
960 self.modulus.encoded_len()? + self.public_exponent.encoded_len()?
961 }
962
963 fn encode_value(&self, writer: &mut impl Writer) -> der::Result<()> {
964 self.modulus.encode(writer)?;
965 self.public_exponent.encode(writer)?;
966 Ok(())
967 }
968}
969
970impl<'a> Sequence<'a> for RsaPublicKey<'a> {}
971
972#[derive(Clone, Debug, Copy, PartialEq, Eq)]
976enum Version {
977 V1 = 0,
979
980 V2 = 1,
982}
983
984impl Version {
985 pub fn has_public_key(self) -> bool {
987 match self {
988 Version::V1 => false,
989 Version::V2 => true,
990 }
991 }
992}
993
994impl<'a> Decode<'a> for Version {
995 fn decode<R: Reader<'a>>(decoder: &mut R) -> der::Result<Self> {
996 Version::try_from(u8::decode(decoder)?).map_err(|_| Self::TAG.value_error())
997 }
998}
999
1000impl Encode for Version {
1001 fn encoded_len(&self) -> der::Result<der::Length> {
1002 der::Length::from(1u8).for_tlv()
1003 }
1004
1005 fn encode(&self, writer: &mut impl Writer) -> der::Result<()> {
1006 u8::from(*self).encode(writer)
1007 }
1008}
1009
1010impl From<Version> for u8 {
1011 fn from(version: Version) -> Self {
1012 version as u8
1013 }
1014}
1015
1016impl TryFrom<u8> for Version {
1017 type Error = der::Error;
1018 fn try_from(byte: u8) -> Result<Version, der::Error> {
1019 match byte {
1020 0 => Ok(Version::V1),
1021 1 => Ok(Version::V2),
1022 _ => Err(Self::TAG.value_error()),
1023 }
1024 }
1025}
1026
1027impl FixedTag for Version {
1028 const TAG: Tag = Tag::Integer;
1029}
1030
1031#[derive(Clone)]
1093struct PrivateKeyInfo<'a> {
1094 pub algorithm: AlgorithmIdentifier<'a>,
1096
1097 pub private_key: &'a [u8],
1099
1100 pub public_key: Option<&'a [u8]>,
1102}
1103
1104impl<'a> PrivateKeyInfo<'a> {
1105 pub fn new(algorithm: AlgorithmIdentifier<'a>, private_key: &'a [u8]) -> Self {
1110 Self {
1111 algorithm,
1112 private_key,
1113 public_key: None,
1114 }
1115 }
1116
1117 pub fn version(&self) -> Version {
1121 if self.public_key.is_some() {
1122 Version::V2
1123 } else {
1124 Version::V1
1125 }
1126 }
1127
1128 fn public_key_bit_string(&self) -> der::Result<Option<ContextSpecific<BitStringRef<'a>>>> {
1130 self.public_key
1131 .map(|pk| {
1132 BitStringRef::from_bytes(pk).map(|value| ContextSpecific {
1133 tag_number: PUBLIC_KEY_TAG,
1134 tag_mode: TagMode::Implicit,
1135 value,
1136 })
1137 })
1138 .transpose()
1139 }
1140}
1141
1142impl<'a> DecodeValue<'a> for PrivateKeyInfo<'a> {
1143 fn decode_value<R: Reader<'a>>(
1144 reader: &mut R,
1145 header: Header,
1146 ) -> der::Result<PrivateKeyInfo<'a>> {
1147 reader.read_nested(header.length, |reader| {
1148 let version = Version::decode(reader)?;
1150 let algorithm = reader.decode()?;
1151 let private_key = OctetStringRef::decode(reader)?.into();
1152 let public_key = reader
1153 .context_specific::<BitStringRef<'_>>(PUBLIC_KEY_TAG, TagMode::Implicit)?
1154 .map(|bs| {
1155 bs.as_bytes()
1156 .ok_or_else(|| der::Tag::BitString.value_error())
1157 })
1158 .transpose()?;
1159
1160 if version.has_public_key() != public_key.is_some() {
1161 return Err(reader.error(
1162 der::Tag::ContextSpecific {
1163 constructed: true,
1164 number: PUBLIC_KEY_TAG,
1165 }
1166 .value_error()
1167 .kind(),
1168 ));
1169 }
1170
1171 while !reader.is_finished() {
1173 reader.decode::<ContextSpecific<AnyRef<'_>>>()?;
1174 }
1175
1176 Ok(Self {
1177 algorithm,
1178 private_key,
1179 public_key,
1180 })
1181 })
1182 }
1183}
1184
1185impl EncodeValue for PrivateKeyInfo<'_> {
1186 fn value_len(&self) -> der::Result<Length> {
1187 self.version().encoded_len()?
1188 + self.algorithm.encoded_len()?
1189 + OctetStringRef::new(self.private_key)?.encoded_len()?
1190 + self.public_key_bit_string()?.encoded_len()?
1191 }
1192
1193 fn encode_value(&self, writer: &mut impl Writer) -> der::Result<()> {
1194 self.version().encode(writer)?;
1195 self.algorithm.encode(writer)?;
1196 OctetStringRef::new(self.private_key)?.encode(writer)?;
1197 self.public_key_bit_string()?.encode(writer)?;
1198 Ok(())
1199 }
1200}
1201
1202impl<'a> Sequence<'a> for PrivateKeyInfo<'a> {}
1203
1204#[derive(Clone)]
1218struct OtherPrimeInfo<'a> {
1219 pub prime: UintRef<'a>,
1221
1222 pub exponent: UintRef<'a>,
1224
1225 pub coefficient: UintRef<'a>,
1227}
1228
1229impl<'a> DecodeValue<'a> for OtherPrimeInfo<'a> {
1230 fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> der::Result<Self> {
1231 reader.read_nested(header.length, |reader| {
1232 Ok(Self {
1233 prime: reader.decode()?,
1234 exponent: reader.decode()?,
1235 coefficient: reader.decode()?,
1236 })
1237 })
1238 }
1239}
1240
1241impl EncodeValue for OtherPrimeInfo<'_> {
1242 fn value_len(&self) -> der::Result<Length> {
1243 self.prime.encoded_len()? + self.exponent.encoded_len()? + self.coefficient.encoded_len()?
1244 }
1245
1246 fn encode_value(&self, writer: &mut impl Writer) -> der::Result<()> {
1247 self.prime.encode(writer)?;
1248 self.exponent.encode(writer)?;
1249 self.coefficient.encode(writer)?;
1250 Ok(())
1251 }
1252}
1253
1254impl<'a> Sequence<'a> for OtherPrimeInfo<'a> {}
1255
1256type OtherPrimeInfos<'a> = Vec<OtherPrimeInfo<'a>>;
1257
1258#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
1273#[repr(u8)]
1274enum Pkcs1Version {
1275 TwoPrime = 0,
1277
1278 Multi = 1,
1280}
1281
1282impl Pkcs1Version {
1283 pub fn is_multi(self) -> bool {
1285 self == Self::Multi
1286 }
1287}
1288
1289impl From<Pkcs1Version> for u8 {
1290 fn from(version: Pkcs1Version) -> Self {
1291 version as u8
1292 }
1293}
1294
1295impl TryFrom<u8> for Pkcs1Version {
1296 type Error = ();
1297 fn try_from(byte: u8) -> Result<Pkcs1Version, ()> {
1298 match byte {
1299 0 => Ok(Pkcs1Version::TwoPrime),
1300 1 => Ok(Pkcs1Version::Multi),
1301 _ => Err(()),
1302 }
1303 }
1304}
1305
1306impl<'a> Decode<'a> for Pkcs1Version {
1307 fn decode<R: Reader<'a>>(decoder: &mut R) -> der::Result<Self> {
1308 Pkcs1Version::try_from(u8::decode(decoder)?).map_err(|_| Self::TAG.value_error())
1309 }
1310}
1311
1312impl Encode for Pkcs1Version {
1313 fn encoded_len(&self) -> der::Result<der::Length> {
1314 der::Length::ONE.for_tlv()
1315 }
1316
1317 fn encode(&self, writer: &mut impl Writer) -> der::Result<()> {
1318 u8::from(*self).encode(writer)
1319 }
1320}
1321
1322impl FixedTag for Pkcs1Version {
1323 const TAG: Tag = Tag::Integer;
1324}
1325
1326#[derive(Clone)]
1350struct RsaPrivateKey<'a> {
1351 pub modulus: UintRef<'a>,
1353
1354 pub public_exponent: UintRef<'a>,
1356
1357 pub private_exponent: UintRef<'a>,
1359
1360 pub prime1: UintRef<'a>,
1362
1363 pub prime2: UintRef<'a>,
1365
1366 pub exponent1: UintRef<'a>,
1368
1369 pub exponent2: UintRef<'a>,
1371
1372 pub coefficient: UintRef<'a>,
1374
1375 pub other_prime_infos: Option<OtherPrimeInfos<'a>>,
1378}
1379
1380impl<'a> RsaPrivateKey<'a> {
1381 fn version(&self) -> Pkcs1Version {
1395 if self.other_prime_infos.is_some() {
1396 Pkcs1Version::Multi
1397 } else {
1398 Pkcs1Version::TwoPrime
1399 }
1400 }
1401}
1402
1403impl<'a> DecodeValue<'a> for RsaPrivateKey<'a> {
1404 fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> der::Result<Self> {
1405 reader.read_nested(header.length, |reader| {
1406 let version = Pkcs1Version::decode(reader)?;
1407
1408 let result = Self {
1409 modulus: reader.decode()?,
1410 public_exponent: reader.decode()?,
1411 private_exponent: reader.decode()?,
1412 prime1: reader.decode()?,
1413 prime2: reader.decode()?,
1414 exponent1: reader.decode()?,
1415 exponent2: reader.decode()?,
1416 coefficient: reader.decode()?,
1417 other_prime_infos: reader.decode()?,
1418 };
1419
1420 if version.is_multi() != result.other_prime_infos.is_some() {
1422 return Err(reader.error(der::ErrorKind::Value { tag: Tag::Integer }));
1423 }
1424
1425 Ok(result)
1426 })
1427 }
1428}
1429
1430impl EncodeValue for RsaPrivateKey<'_> {
1431 fn value_len(&self) -> der::Result<Length> {
1432 self.version().encoded_len()?
1433 + self.modulus.encoded_len()?
1434 + self.public_exponent.encoded_len()?
1435 + self.private_exponent.encoded_len()?
1436 + self.prime1.encoded_len()?
1437 + self.prime2.encoded_len()?
1438 + self.exponent1.encoded_len()?
1439 + self.exponent2.encoded_len()?
1440 + self.coefficient.encoded_len()?
1441 + self.other_prime_infos.encoded_len()?
1442 }
1443
1444 fn encode_value(&self, writer: &mut impl Writer) -> der::Result<()> {
1445 self.version().encode(writer)?;
1446 self.modulus.encode(writer)?;
1447 self.public_exponent.encode(writer)?;
1448 self.private_exponent.encode(writer)?;
1449 self.prime1.encode(writer)?;
1450 self.prime2.encode(writer)?;
1451 self.exponent1.encode(writer)?;
1452 self.exponent2.encode(writer)?;
1453 self.coefficient.encode(writer)?;
1454 self.other_prime_infos.encode(writer)?;
1455 Ok(())
1456 }
1457}
1458
1459impl<'a> Sequence<'a> for RsaPrivateKey<'a> {}