1 //! PKCS#8 private key tests
2
3 use der::asn1::ObjectIdentifier;
4 use hex_literal::hex;
5 use pkcs8::{PrivateKeyInfo, Version};
6
7 #[cfg(feature = "alloc")]
8 use der::Encode;
9
10 #[cfg(feature = "pem")]
11 use der::{pem::LineEnding, EncodePem};
12
13 /// Elliptic Curve (P-256) PKCS#8 private key encoded as ASN.1 DER
14 const EC_P256_DER_EXAMPLE: &[u8] = include_bytes!("examples/p256-priv.der");
15
16 /// Ed25519 PKCS#8 v1 private key encoded as ASN.1 DER
17 const ED25519_DER_V1_EXAMPLE: &[u8] = include_bytes!("examples/ed25519-priv-pkcs8v1.der");
18
19 /// Ed25519 PKCS#8 v2 private key + public key encoded as ASN.1 DER
20 const ED25519_DER_V2_EXAMPLE: &[u8] = include_bytes!("examples/ed25519-priv-pkcs8v2.der");
21
22 /// RSA-2048 PKCS#8 private key encoded as ASN.1 DER
23 const RSA_2048_DER_EXAMPLE: &[u8] = include_bytes!("examples/rsa2048-priv.der");
24
25 /// X25519 PKCS#8 private key encoded as ASN.1 DER
26 const X25519_DER_EXAMPLE: &[u8] = include_bytes!("examples/x25519-priv.der");
27
28 /// Elliptic Curve (P-256) PKCS#8 private key encoded as PEM
29 #[cfg(feature = "pem")]
30 const EC_P256_PEM_EXAMPLE: &str = include_str!("examples/p256-priv.pem");
31
32 /// Ed25519 PKCS#8 private key encoded as PEM
33 #[cfg(feature = "pem")]
34 const ED25519_PEM_V1_EXAMPLE: &str = include_str!("examples/ed25519-priv-pkcs8v1.pem");
35
36 /// RSA-2048 PKCS#8 private key encoded as PEM
37 #[cfg(feature = "pem")]
38 const RSA_2048_PEM_EXAMPLE: &str = include_str!("examples/rsa2048-priv.pem");
39
40 /// X25519 PKCS#8 private key encoded as PEM
41 #[cfg(feature = "pem")]
42 const X25519_PEM_EXAMPLE: &str = include_str!("examples/x25519-priv.pem");
43
44 #[test]
decode_ec_p256_der()45 fn decode_ec_p256_der() {
46 let pk = PrivateKeyInfo::try_from(EC_P256_DER_EXAMPLE).unwrap();
47
48 assert_eq!(pk.version(), Version::V1);
49 assert_eq!(pk.algorithm.oid, "1.2.840.10045.2.1".parse().unwrap());
50
51 assert_eq!(
52 pk.algorithm
53 .parameters
54 .unwrap()
55 .decode_as::<ObjectIdentifier>()
56 .unwrap(),
57 "1.2.840.10045.3.1.7".parse().unwrap()
58 );
59
60 // Extracted with:
61 // $ openssl asn1parse -inform der -in tests/examples/p256-priv.der
62 assert_eq!(pk.private_key, &hex!("306B020101042069624171561A63340DE0E7D869F2A05492558E1A04868B6A9F854A866788188DA144034200041CACFFB55F2F2CEFD89D89EB374B2681152452802DEEA09916068137D839CF7FC481A44492304D7EF66AC117BEFE83A8D08F155F2B52F9F618DD447029048E0F")[..]);
63 }
64
65 // Test vector from RFC8410 Section 10.3:
66 // https://datatracker.ietf.org/doc/html/rfc8410#section-10.3
67 #[test]
decode_ed25519_der_v1()68 fn decode_ed25519_der_v1() {
69 let pk = PrivateKeyInfo::try_from(ED25519_DER_V1_EXAMPLE).unwrap();
70 assert_eq!(pk.version(), Version::V1);
71 assert_eq!(pk.algorithm.oid, "1.3.101.112".parse().unwrap());
72 assert_eq!(pk.algorithm.parameters, None);
73
74 // Extracted with:
75 // $ openssl asn1parse -inform der -in tests/examples/ed25519-priv.der
76 assert_eq!(
77 pk.private_key,
78 &hex!("042017ED9C73E9DB649EC189A612831C5FC570238207C1AA9DFBD2C53E3FF5E5EA85")[..]
79 );
80 }
81
82 // Test vector from RFC8410 Section 10.3:
83 // https://datatracker.ietf.org/doc/html/rfc8410#section-10.3
84 #[test]
decode_ed25519_der_v2()85 fn decode_ed25519_der_v2() {
86 // Extracted with:
87 // $ openssl asn1parse -inform der -in tests/examples/ed25519-priv-pkcs8v2.der
88 const PRIV_KEY: [u8; 34] =
89 hex!("0420D4EE72DBF913584AD5B6D8F1F769F8AD3AFE7C28CBF1D4FBE097A88F44755842");
90 const PUB_KEY: [u8; 32] =
91 hex!("19BF44096984CDFE8541BAC167DC3B96C85086AA30B6B6CB0C5C38AD703166E1");
92
93 let pk = PrivateKeyInfo::try_from(ED25519_DER_V2_EXAMPLE).unwrap();
94 assert_eq!(pk.version(), Version::V2);
95 assert_eq!(pk.algorithm.oid, "1.3.101.112".parse().unwrap());
96 assert_eq!(pk.algorithm.parameters, None);
97 assert_eq!(pk.private_key, PRIV_KEY);
98 assert_eq!(pk.public_key, Some(&PUB_KEY[..]));
99 }
100
101 #[test]
decode_rsa_2048_der()102 fn decode_rsa_2048_der() {
103 let pk = PrivateKeyInfo::try_from(RSA_2048_DER_EXAMPLE).unwrap();
104 assert_eq!(pk.version(), Version::V1);
105 assert_eq!(pk.algorithm.oid, "1.2.840.113549.1.1.1".parse().unwrap());
106 assert!(pk.algorithm.parameters.unwrap().is_null());
107
108 // Extracted with:
109 // $ openssl asn1parse -inform der -in tests/examples/rsa2048-priv.der
110 assert_eq!(pk.private_key, &hex!("308204A30201000282010100B6C42C515F10A6AAF282C63EDBE24243A170F3FA2633BD4833637F47CA4F6F36E03A5D29EFC3191AC80F390D874B39E30F414FCEC1FCA0ED81E547EDC2CD382C76F61C9018973DB9FA537972A7C701F6B77E0982DFC15FC01927EE5E7CD94B4F599FF07013A7C8281BDF22DCBC9AD7CABB7C4311C982F58EDB7213AD4558B332266D743AED8192D1884CADB8B14739A8DADA66DC970806D9C7AC450CB13D0D7C575FB198534FC61BC41BC0F0574E0E0130C7BBBFBDFDC9F6A6E2E3E2AFF1CBEAC89BA57884528D55CFB08327A1E8C89F4E003CF2888E933241D9D695BCBBACDC90B44E3E095FA37058EA25B13F5E295CBEAC6DE838AB8C50AF61E298975B872F0203010001028201007ECC8362C0EDB0741164215E22F74AB9D91BA06900700CF63690E5114D8EE6BDCFBB2E3F9614692A677A083F168A5E52E5968E6407B9D97C6E0E4064F82DA0B758A14F17B9B7D41F5F48E28D6551704F56E69E7AA9FA630FC76428C06D25E455DCFC55B7AC2B4F76643FDED3FE15FF78ABB27E65ACC4AAD0BDF6DB27EF60A6910C5C4A085ED43275AB19C1D997A32C6EFFCE7DF2D1935F6E601EEDE161A12B5CC27CA21F81D2C99C3D1EA08E90E3053AB09BEFA724DEF0D0C3A3C1E9740C0D9F76126A149EC0AA7D8078205484254D951DB07C4CF91FB6454C096588FD5924DBABEB359CA2025268D004F9D66EB3D6F7ADC1139BAD40F16DDE639E11647376C102818100DCC061242D4E92AFAEE72AC513CA65B9F77036F9BD7E0E6E61461A7EF7654225EC153C7E5C31A6157A6E5A13FF6E178E8758C1CB33D9D6BBE3179EF18998E422ECDCBED78F4ECFDBE5F4FCD8AEC2C9D0DC86473CA9BD16D9D238D21FB5DDEFBEB143CA61D0BD6AA8D91F33A097790E9640DBC91085DC5F26343BA3138F6B2D6702818100D3F314757E40E954836F92BE24236AF2F0DA04A34653C180AF67E960086D93FDE65CB23EFD9D09374762F5981E361849AF68CDD75394FF6A4E06EB69B209E4228DB2DFA70E40F7F9750A528176647B788D0E5777A2CB8B22E3CD267FF70B4F3B02D3AAFB0E18C590A564B03188B0AA5FC48156B07622214243BD1227EFA7F2F902818100CE68B7AC1B0D100D636E55488753C5C09843FDB390E2705DF7689457C9BD8D9765E30978617E2EFC8048F4C324206DB86087B654E97BB3D464E7EE3F8CD83FE10436F7DF18E9A963C4E64911D67EDE34042F2E26E3D3A1AD346ADAD6B9B7F67708CB094E62DEE9FF4D5D6669AF988AF2255D1CE8ED317C6A7D8691DA354D12DB02818025F6E5944220286B4DFBBF4235C0EE5843D2198091895120D6CA7B200B826D3ECE738E2E00498FAC0A2A6CA969C7F0C3CA1AB0BC40297132BE7538D7BEDF4CB0EFC6B98EF7DBA54F56AA99AABCE534C49C27947D4678C51C63C78C7CE1687231B4C8EB587AE6EF0480CBAF4FC0173CFD587A7E67AF515FB9B9DE75111839722902818031995406D406207CADEAEA35B38D040C5F8A9A1AE0827E9ED06B153D83B6821935B4B36A82BE9D56C791B58C27271A5793D53A1D657C08997960B1433E5171987F452F144A7C72306D63E1D3FFC0B71B75AB08F2E45A482E988451CBE478E12EB228D07456C924B66F6CED048D853F533E31A68614F1C3CE6D8EC9983CE72AF7")[..]);
111 }
112
113 #[test]
decode_x25519_der()114 fn decode_x25519_der() {
115 let pk = PrivateKeyInfo::try_from(X25519_DER_EXAMPLE).unwrap();
116 assert_eq!(pk.version(), Version::V1);
117 assert_eq!(pk.algorithm.oid, "1.3.101.110".parse().unwrap());
118 assert_eq!(pk.algorithm.parameters, None);
119
120 // Extracted with:
121 // $ openssl asn1parse -inform der -in tests/examples/x25519-priv.der
122 assert_eq!(
123 pk.private_key,
124 &hex!("04207060252933AC6E7A4A9B0EB2632C5A040A87257ADB869A3ECCC3D16B724F2647")[..]
125 );
126 }
127
128 #[test]
129 #[cfg(feature = "alloc")]
encode_ec_p256_der()130 fn encode_ec_p256_der() {
131 let pk = PrivateKeyInfo::try_from(EC_P256_DER_EXAMPLE).unwrap();
132 let pk_encoded = pk.to_der().unwrap();
133 assert_eq!(EC_P256_DER_EXAMPLE, pk_encoded);
134 }
135
136 #[test]
137 #[cfg(feature = "alloc")]
encode_ed25519_der_v1()138 fn encode_ed25519_der_v1() {
139 let pk = PrivateKeyInfo::try_from(ED25519_DER_V1_EXAMPLE).unwrap();
140 assert_eq!(ED25519_DER_V1_EXAMPLE, pk.to_der().unwrap());
141 }
142
143 #[test]
144 #[cfg(all(feature = "alloc", feature = "subtle"))]
encode_ed25519_der_v2()145 fn encode_ed25519_der_v2() {
146 let private_key = PrivateKeyInfo::try_from(ED25519_DER_V2_EXAMPLE).unwrap();
147 let private_der = private_key.to_der().unwrap();
148 assert_eq!(
149 private_key,
150 PrivateKeyInfo::try_from(private_der.as_ref()).unwrap()
151 );
152 }
153
154 #[test]
155 #[cfg(feature = "alloc")]
encode_rsa_2048_der()156 fn encode_rsa_2048_der() {
157 let pk = PrivateKeyInfo::try_from(RSA_2048_DER_EXAMPLE).unwrap();
158 assert_eq!(RSA_2048_DER_EXAMPLE, &pk.to_der().unwrap());
159 }
160
161 #[test]
162 #[cfg(feature = "pem")]
encode_ec_p256_pem()163 fn encode_ec_p256_pem() {
164 let pk = PrivateKeyInfo::try_from(EC_P256_DER_EXAMPLE).unwrap();
165 assert_eq!(EC_P256_PEM_EXAMPLE, pk.to_pem(LineEnding::LF).unwrap());
166 }
167
168 #[test]
169 #[cfg(feature = "pem")]
encode_ed25519_pem()170 fn encode_ed25519_pem() {
171 let pk = PrivateKeyInfo::try_from(ED25519_DER_V1_EXAMPLE).unwrap();
172 assert_eq!(ED25519_PEM_V1_EXAMPLE, pk.to_pem(LineEnding::LF).unwrap());
173 }
174
175 #[test]
176 #[cfg(feature = "pem")]
encode_rsa_2048_pem()177 fn encode_rsa_2048_pem() {
178 let pk = PrivateKeyInfo::try_from(RSA_2048_DER_EXAMPLE).unwrap();
179 assert_eq!(RSA_2048_PEM_EXAMPLE, pk.to_pem(LineEnding::LF).unwrap());
180 }
181
182 #[test]
183 #[cfg(feature = "pem")]
encode_x25519_pem()184 fn encode_x25519_pem() {
185 let pk = PrivateKeyInfo::try_from(X25519_DER_EXAMPLE).unwrap();
186 assert_eq!(X25519_PEM_EXAMPLE, pk.to_pem(LineEnding::LF).unwrap());
187 }
188