1 //! Encrypted PKCS#8 private key tests.
2 
3 #![cfg(feature = "pkcs5")]
4 
5 use hex_literal::hex;
6 use pkcs8::{pkcs5::pbes2, EncryptedPrivateKeyInfo, PrivateKeyInfo};
7 
8 #[cfg(feature = "alloc")]
9 use der::Encode;
10 
11 #[cfg(feature = "pem")]
12 use der::EncodePem;
13 
14 /// Ed25519 PKCS#8 private key plaintext encoded as ASN.1 DER
15 #[cfg(feature = "encryption")]
16 const ED25519_DER_PLAINTEXT_EXAMPLE: &[u8] = include_bytes!("examples/ed25519-priv-pkcs8v1.der");
17 
18 /// Ed25519 PKCS#8 encrypted private key (PBES2 + AES-128-CBC + PBKDF2-SHA1) encoded as ASN.1 DER.
19 ///
20 /// Generated using:
21 ///
22 /// ```
23 /// $ openssl pkcs8 -v2 aes256-cbc -v2prf hmacWithSHA1 -topk8 -inform der -in ed25519-priv.der -outform der -out ed25519-encpriv-aes128-pbkdf2-sha1.der
24 /// ```
25 const ED25519_DER_AES128_PBKDF2_SHA1_EXAMPLE: &[u8] =
26     include_bytes!("examples/ed25519-encpriv-aes128-pbkdf2-sha1.der");
27 
28 /// Ed25519 PKCS#8 encrypted private key (PBES2 + AES-256-CBC + PBKDF2-SHA256) encoded as ASN.1 DER.
29 ///
30 /// Generated using:
31 ///
32 /// ```
33 /// $ openssl pkcs8 -v2 aes256-cbc -v2prf hmacWithSHA256 -topk8 -inform der -in ed25519-priv.der -outform der -out ed25519-encpriv-aes256-pbkdf2-sha256.der
34 /// ```
35 const ED25519_DER_AES256_PBKDF2_SHA256_EXAMPLE: &[u8] =
36     include_bytes!("examples/ed25519-encpriv-aes256-pbkdf2-sha256.der");
37 
38 /// Ed25519 PKCS#8 encrypted private key (PBES2 + AES-256-CBC + scrypt) encoded as ASN.1 DER.
39 ///
40 /// Generated using:
41 ///
42 /// ```
43 /// $ openssl pkcs8 -v2 aes256-cbc -scrypt -topk8 -inform der -in ed25519-priv.der -outform der -out ed25519-encpriv-aes256-scrypt.der
44 /// ```
45 #[cfg(feature = "encryption")]
46 const ED25519_DER_AES256_SCRYPT_EXAMPLE: &[u8] =
47     include_bytes!("examples/ed25519-encpriv-aes256-scrypt.der");
48 
49 /// Ed25519 PKCS#8 encrypted private key encoded as PEM
50 #[cfg(feature = "pem")]
51 const ED25519_PEM_AES256_PBKDF2_SHA256_EXAMPLE: &str =
52     include_str!("examples/ed25519-encpriv-aes256-pbkdf2-sha256.pem");
53 
54 /// Ed25519 PKCS#8 encrypted private key (PBES2 + 3DES + PBKDF2-SHA256) encoded as ASN.1 DER
55 ///
56 /// Generated using:
57 ///
58 /// ```
59 /// $ openssl pkcs8 -v2 des3 -topk8 -inform der -in ed25519-priv-pkcs8v1.der -outform der -out ed25519-encpriv-des3-pbkdf2-sha256.der
60 /// ```
61 #[cfg(feature = "3des")]
62 const ED25519_DER_DES3_PBKDF2_SHA256_EXAMPLE: &[u8] =
63     include_bytes!("examples/ed25519-encpriv-des3-pbkdf2-sha256.der");
64 
65 /// Ed25519 PKCS#8 encrypted private key (PBES2 + DES + PBKDF2-SHA256) encoded as ASN.1 DER
66 ///
67 /// Generated using:
68 ///
69 /// ```
70 /// $ openssl pkcs8 -v2 des -topk8 -inform der -in ed25519-priv-pkcs8v1.der -outform der -out ed25519-encpriv-des3-pbkdf2-sha256.der
71 /// ```
72 #[cfg(feature = "des-insecure")]
73 const ED25519_DER_DES_PBKDF2_SHA256_EXAMPLE: &[u8] =
74     include_bytes!("examples/ed25519-encpriv-des-pbkdf2-sha256.der");
75 
76 /// Password used to encrypt the keys.
77 #[cfg(feature = "encryption")]
78 const PASSWORD: &[u8] = b"hunter42"; // Bad password; don't actually use outside tests!
79 
80 #[test]
decode_ed25519_encpriv_aes128_pbkdf2_sha1_der()81 fn decode_ed25519_encpriv_aes128_pbkdf2_sha1_der() {
82     let pk = EncryptedPrivateKeyInfo::try_from(ED25519_DER_AES128_PBKDF2_SHA1_EXAMPLE).unwrap();
83 
84     assert_eq!(
85         pk.encryption_algorithm.oid(),
86         "1.2.840.113549.1.5.13".parse().unwrap()
87     ); // PBES2
88 
89     let pbes2_params = pk.encryption_algorithm.pbes2().unwrap();
90     let pbkdf2_params = pbes2_params.kdf.pbkdf2().unwrap();
91 
92     assert_eq!(pbkdf2_params.salt, hex!("e8765e01e43b6bad"));
93     assert_eq!(pbkdf2_params.iteration_count, 2048);
94     assert_eq!(pbkdf2_params.key_length, None);
95     assert_eq!(pbkdf2_params.prf, pbes2::Pbkdf2Prf::HmacWithSha1);
96 
97     match pbes2_params.encryption {
98         pbes2::EncryptionScheme::Aes128Cbc { iv } => {
99             assert_eq!(iv, &hex!("223080a71bcd2b9a256d876c924979d2"));
100         }
101         other => panic!("unexpected encryption scheme: {:?}", other),
102     }
103 
104     // Extracted with:
105     // $ openssl asn1parse -inform der -in tests/examples/ed25519-encpriv-aes128-sha1.der
106     assert_eq!(
107         pk.encrypted_data,
108         &hex!("4B4D091548EAC381EE7663B21234CD4FF3C9DF664D713394CACCEA7C9B982BD8F29910FABCA4BF7BE0431FAC5C4D657BE997C1F5BF40E2DA465AC1FCC2E30470")
109     );
110 }
111 
112 #[test]
decode_ed25519_encpriv_aes256_pbkdf2_sha256_der()113 fn decode_ed25519_encpriv_aes256_pbkdf2_sha256_der() {
114     let pk = EncryptedPrivateKeyInfo::try_from(ED25519_DER_AES256_PBKDF2_SHA256_EXAMPLE).unwrap();
115 
116     assert_eq!(
117         pk.encryption_algorithm.oid(),
118         "1.2.840.113549.1.5.13".parse().unwrap()
119     ); // PBES2
120 
121     let pbes2_params = pk.encryption_algorithm.pbes2().unwrap();
122     let pbkdf2_params = pbes2_params.kdf.pbkdf2().unwrap();
123 
124     assert_eq!(pbkdf2_params.salt, hex!("79d982e70df91a88"));
125     assert_eq!(pbkdf2_params.iteration_count, 2048);
126     assert_eq!(pbkdf2_params.key_length, None);
127     assert_eq!(pbkdf2_params.prf, pbes2::Pbkdf2Prf::HmacWithSha256);
128 
129     match pbes2_params.encryption {
130         pbes2::EncryptionScheme::Aes256Cbc { iv } => {
131             assert_eq!(iv, &hex!("b2d02d78b2efd9dff694cf8e0af40925"));
132         }
133         other => panic!("unexpected encryption scheme: {:?}", other),
134     }
135 
136     // Extracted with:
137     // $ openssl asn1parse -inform der -in tests/examples/ed25519-encpriv-aes256-sha256.der
138     assert_eq!(
139         pk.encrypted_data,
140         &hex!("D0CD6C770F4BB87176422305C17401809E226674CE74185D221BFDAA95069890C8882FCE02B05D41BCBF54B035595BCD4154B32593708469B86AACF8815A7B2B")
141     );
142 }
143 
144 #[cfg(feature = "encryption")]
145 #[test]
decrypt_ed25519_der_encpriv_aes256_pbkdf2_sha256()146 fn decrypt_ed25519_der_encpriv_aes256_pbkdf2_sha256() {
147     let enc_pk =
148         EncryptedPrivateKeyInfo::try_from(ED25519_DER_AES256_PBKDF2_SHA256_EXAMPLE).unwrap();
149     let pk = enc_pk.decrypt(PASSWORD).unwrap();
150     assert_eq!(pk.as_bytes(), ED25519_DER_PLAINTEXT_EXAMPLE);
151 }
152 
153 #[cfg(feature = "encryption")]
154 #[test]
decrypt_ed25519_der_encpriv_aes256_scrypt()155 fn decrypt_ed25519_der_encpriv_aes256_scrypt() {
156     let enc_pk = EncryptedPrivateKeyInfo::try_from(ED25519_DER_AES256_SCRYPT_EXAMPLE).unwrap();
157     let pk = enc_pk.decrypt(PASSWORD).unwrap();
158     assert_eq!(pk.as_bytes(), ED25519_DER_PLAINTEXT_EXAMPLE);
159 }
160 
161 #[cfg(feature = "encryption")]
162 #[test]
encrypt_ed25519_der_encpriv_aes256_pbkdf2_sha256()163 fn encrypt_ed25519_der_encpriv_aes256_pbkdf2_sha256() {
164     let pbes2_params = pkcs5::pbes2::Parameters::pbkdf2_sha256_aes256cbc(
165         2048,
166         &hex!("79d982e70df91a88"),
167         &hex!("b2d02d78b2efd9dff694cf8e0af40925"),
168     )
169     .unwrap();
170 
171     let pk_plaintext = PrivateKeyInfo::try_from(ED25519_DER_PLAINTEXT_EXAMPLE).unwrap();
172     let pk_encrypted = pk_plaintext
173         .encrypt_with_params(pbes2_params, PASSWORD)
174         .unwrap();
175 
176     assert_eq!(
177         pk_encrypted.as_bytes(),
178         ED25519_DER_AES256_PBKDF2_SHA256_EXAMPLE
179     );
180 }
181 
182 #[cfg(feature = "encryption")]
183 #[test]
encrypt_ed25519_der_encpriv_aes256_scrypt()184 fn encrypt_ed25519_der_encpriv_aes256_scrypt() {
185     let scrypt_params = pkcs5::pbes2::Parameters::scrypt_aes256cbc(
186         pkcs5::scrypt::Params::new(15, 8, 1, 32).unwrap(),
187         &hex!("E6211E2348AD69E0"),
188         &hex!("9BD0A6251F2254F9FD5963887C27CF01"),
189     )
190     .unwrap();
191 
192     let pk_plaintext = PrivateKeyInfo::try_from(ED25519_DER_PLAINTEXT_EXAMPLE).unwrap();
193     let pk_encrypted = pk_plaintext
194         .encrypt_with_params(scrypt_params, PASSWORD)
195         .unwrap();
196 
197     assert_eq!(pk_encrypted.as_bytes(), ED25519_DER_AES256_SCRYPT_EXAMPLE);
198 }
199 
200 #[test]
201 #[cfg(feature = "alloc")]
encode_ed25519_encpriv_aes256_pbkdf2_sha256_der()202 fn encode_ed25519_encpriv_aes256_pbkdf2_sha256_der() {
203     let pk = EncryptedPrivateKeyInfo::try_from(ED25519_DER_AES256_PBKDF2_SHA256_EXAMPLE).unwrap();
204     assert_eq!(
205         ED25519_DER_AES256_PBKDF2_SHA256_EXAMPLE,
206         &pk.to_der().unwrap()
207     );
208 }
209 
210 #[test]
211 #[cfg(feature = "pem")]
encode_ed25519_encpriv_aes256_pbkdf2_sha256_pem()212 fn encode_ed25519_encpriv_aes256_pbkdf2_sha256_pem() {
213     let pk = EncryptedPrivateKeyInfo::try_from(ED25519_DER_AES256_PBKDF2_SHA256_EXAMPLE).unwrap();
214     assert_eq!(
215         ED25519_PEM_AES256_PBKDF2_SHA256_EXAMPLE,
216         pk.to_pem(Default::default()).unwrap()
217     );
218 }
219 
220 #[test]
221 #[cfg(feature = "3des")]
decrypt_ed25519_der_encpriv_des3_pbkdf2_sha256()222 fn decrypt_ed25519_der_encpriv_des3_pbkdf2_sha256() {
223     let enc_pk = EncryptedPrivateKeyInfo::try_from(ED25519_DER_DES3_PBKDF2_SHA256_EXAMPLE).unwrap();
224     let pk = enc_pk.decrypt(PASSWORD).unwrap();
225     assert_eq!(pk.as_bytes(), ED25519_DER_PLAINTEXT_EXAMPLE);
226 }
227 
228 #[test]
229 #[cfg(feature = "des-insecure")]
decrypt_ed25519_der_encpriv_des_pbkdf2_sha256()230 fn decrypt_ed25519_der_encpriv_des_pbkdf2_sha256() {
231     let enc_pk = EncryptedPrivateKeyInfo::try_from(ED25519_DER_DES_PBKDF2_SHA256_EXAMPLE).unwrap();
232     let pk = enc_pk.decrypt(PASSWORD).unwrap();
233     assert_eq!(pk.as_bytes(), ED25519_DER_PLAINTEXT_EXAMPLE);
234 }
235