1#[cfg(feature = "std")]
2use ct_codecs::Encoder;
3use ct_codecs::{Base64, Decoder};
4
5use super::{Error, KeyPair, PublicKey, SecretKey, Seed};
6
7const DER_HEADER_SK: [u8; 16] = [48, 46, 2, 1, 0, 48, 5, 6, 3, 43, 101, 112, 4, 34, 4, 32];
8
9const DER_HEADER_PK: [u8; 12] = [48, 42, 48, 5, 6, 3, 43, 101, 112, 3, 33, 0];
10
11impl KeyPair {
12 pub fn from_der(der: &[u8]) -> Result<Self, Error> {
14 if der.len() != DER_HEADER_SK.len() + Seed::BYTES || der[0..16] != DER_HEADER_SK {
15 return Err(Error::ParseError);
16 }
17 let mut seed = [0u8; Seed::BYTES];
18 seed.copy_from_slice(&der[16..]);
19 let kp = KeyPair::from_seed(Seed::new(seed));
20 Ok(kp)
21 }
22
23 pub fn from_pem(pem: &str) -> Result<Self, Error> {
25 let mut it = pem.split("-----BEGIN PRIVATE KEY-----");
26 let _ = it.next().ok_or(Error::ParseError)?;
27 let inner = it.next().ok_or(Error::ParseError)?;
28 let mut it = inner.split("-----END PRIVATE KEY-----");
29 let b64 = it.next().ok_or(Error::ParseError)?;
30 let _ = it.next().ok_or(Error::ParseError)?;
31 let mut der = [0u8; 16 + Seed::BYTES];
32 Base64::decode(&mut der, b64, Some(b"\r\n\t ")).map_err(|_| Error::ParseError)?;
33 Self::from_der(&der)
34 }
35
36 #[cfg(feature = "std")]
38 pub fn to_pem(&self) -> String {
39 format!("{}\n{}\n", self.sk.to_pem().trim(), self.pk.to_pem().trim())
40 }
41}
42
43impl SecretKey {
44 pub fn from_der(der: &[u8]) -> Result<Self, Error> {
46 let kp = KeyPair::from_der(der)?;
47 Ok(kp.sk)
48 }
49
50 pub fn from_pem(pem: &str) -> Result<Self, Error> {
52 let kp = KeyPair::from_pem(pem)?;
53 Ok(kp.sk)
54 }
55
56 #[cfg(feature = "std")]
58 pub fn to_der(&self) -> Vec<u8> {
59 let mut der = [0u8; 16 + Seed::BYTES];
60 der[0..16].copy_from_slice(&DER_HEADER_SK);
61 der[16..].copy_from_slice(self.seed().as_ref());
62 der.to_vec()
63 }
64
65 #[cfg(feature = "std")]
67 pub fn to_pem(&self) -> String {
68 let b64 = Base64::encode_to_string(self.to_der()).unwrap();
69 format!(
70 "-----BEGIN PRIVATE KEY-----\n{}\n-----END PRIVATE KEY-----\n",
71 b64
72 )
73 }
74}
75
76impl PublicKey {
77 pub fn from_der(der: &[u8]) -> Result<Self, Error> {
79 if der.len() != DER_HEADER_PK.len() + PublicKey::BYTES || der[0..12] != DER_HEADER_PK {
80 return Err(Error::ParseError);
81 }
82 let mut pk = [0u8; PublicKey::BYTES];
83 pk.copy_from_slice(&der[12..]);
84 let pk = PublicKey::new(pk);
85 Ok(pk)
86 }
87
88 pub fn from_pem(pem: &str) -> Result<Self, Error> {
90 let mut it = pem.split("-----BEGIN PUBLIC KEY-----");
91 let _ = it.next().ok_or(Error::ParseError)?;
92 let inner = it.next().ok_or(Error::ParseError)?;
93 let mut it = inner.split("-----END PUBLIC KEY-----");
94 let b64 = it.next().ok_or(Error::ParseError)?;
95 let _ = it.next().ok_or(Error::ParseError)?;
96 let mut der = [0u8; 12 + PublicKey::BYTES];
97 Base64::decode(&mut der, b64, Some(b"\r\n\t ")).map_err(|_| Error::ParseError)?;
98 Self::from_der(&der)
99 }
100
101 #[cfg(feature = "std")]
103 pub fn to_der(&self) -> Vec<u8> {
104 let mut der = [0u8; 12 + PublicKey::BYTES];
105 der[0..12].copy_from_slice(&DER_HEADER_PK);
106 der[12..].copy_from_slice(self.as_ref());
107 der.to_vec()
108 }
109
110 #[cfg(feature = "std")]
112 pub fn to_pem(&self) -> String {
113 let b64 = Base64::encode_to_string(self.to_der()).unwrap();
114 format!(
115 "-----BEGIN PUBLIC KEY-----\n{}\n-----END PUBLIC KEY-----\n",
116 b64
117 )
118 }
119}
120
121#[test]
122fn test_pem() {
123 let sk_pem = "-----BEGIN PRIVATE KEY-----
124MC4CAQAwBQYDK2VwBCIEIMXY1NUbUe/3dW2YUoKW5evsnCJPMfj60/q0RzGne3gg
125-----END PRIVATE KEY-----\n";
126 let sk = SecretKey::from_pem(sk_pem).unwrap();
127
128 let pk_pem = "-----BEGIN PUBLIC KEY-----
129MCowBQYDK2VwAyEAyrRjJfTnhMcW5igzYvPirFW5eUgMdKeClGzQhd4qw+Y=
130-----END PUBLIC KEY-----\n";
131 let pk = PublicKey::from_pem(pk_pem).unwrap();
132
133 assert_eq!(sk.public_key(), pk);
134
135 #[cfg(features = "std")]
136 {
137 let sk_pem2 = sk.to_pem();
138 let pk_pem2 = pk.to_pem();
139 assert_eq!(sk_pem, sk_pem2);
140 assert_eq!(pk_pem, pk_pem2);
141 }
142}
143
144#[test]
145fn test_der() {
146 let kp = KeyPair::generate();
147 let sk_der = kp.sk.to_der();
148 let sk2 = SecretKey::from_der(&sk_der).unwrap();
149 let pk_der = kp.pk.to_der();
150 let pk2 = PublicKey::from_der(&pk_der).unwrap();
151 assert_eq!(kp.sk, sk2);
152 assert_eq!(kp.pk, pk2);
153}