summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/pkcs12/p12_kiss.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/pkcs12/p12_kiss.c')
-rw-r--r--src/lib/libcrypto/pkcs12/p12_kiss.c175
1 files changed, 111 insertions, 64 deletions
diff --git a/src/lib/libcrypto/pkcs12/p12_kiss.c b/src/lib/libcrypto/pkcs12/p12_kiss.c
index 767e1303da..885087ad00 100644
--- a/src/lib/libcrypto/pkcs12/p12_kiss.c
+++ b/src/lib/libcrypto/pkcs12/p12_kiss.c
@@ -62,9 +62,18 @@
62 62
63/* Simplified PKCS#12 routines */ 63/* Simplified PKCS#12 routines */
64 64
65static int parse_pk12( PKCS12 *p12, const char *pass, int passlen, EVP_PKEY **pkey, X509 **cert, STACK **ca); 65static int parse_pk12( PKCS12 *p12, const char *pass, int passlen,
66static int parse_bags( STACK *bags, const char *pass, int passlen, EVP_PKEY **pkey, X509 **cert, STACK **ca, ASN1_OCTET_STRING **keyid, char *keymatch); 66 EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca);
67static int parse_bag( PKCS12_SAFEBAG *bag, const char *pass, int passlen, EVP_PKEY **pkey, X509 **cert, STACK **ca, ASN1_OCTET_STRING **keyid, char *keymatch); 67
68static int parse_bags( STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass,
69 int passlen, EVP_PKEY **pkey, X509 **cert,
70 STACK_OF(X509) **ca, ASN1_OCTET_STRING **keyid,
71 char *keymatch);
72
73static int parse_bag( PKCS12_SAFEBAG *bag, const char *pass, int passlen,
74 EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca,
75 ASN1_OCTET_STRING **keyid, char *keymatch);
76
68/* Parse and decrypt a PKCS#12 structure returning user key, user cert 77/* Parse and decrypt a PKCS#12 structure returning user key, user cert
69 * and other (CA) certs. Note either ca should be NULL, *ca should be NULL, 78 * and other (CA) certs. Note either ca should be NULL, *ca should be NULL,
70 * or it should point to a valid STACK structure. pkey and cert can be 79 * or it should point to a valid STACK structure. pkey and cert can be
@@ -72,94 +81,111 @@ static int parse_bag( PKCS12_SAFEBAG *bag, const char *pass, int passlen, EVP_PK
72 */ 81 */
73 82
74int PKCS12_parse (PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, 83int PKCS12_parse (PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert,
75 STACK **ca) 84 STACK_OF(X509) **ca)
76{ 85{
77 86
78/* Check for NULL PKCS12 structure */ 87 /* Check for NULL PKCS12 structure */
79 88
80if(!p12) { 89 if(!p12) {
81 PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_INVALID_NULL_PKCS12_POINTER); 90 PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_INVALID_NULL_PKCS12_POINTER);
82 return 0;
83}
84
85/* Allocate stack for ca certificates if needed */
86if ((ca != NULL) && (*ca == NULL)) {
87 if (!(*ca = sk_new(NULL))) {
88 PKCS12err(PKCS12_F_PKCS12_PARSE,ERR_R_MALLOC_FAILURE);
89 return 0; 91 return 0;
90 } 92 }
91}
92 93
93if(pkey) *pkey = NULL; 94 /* Allocate stack for ca certificates if needed */
94if(cert) *cert = NULL; 95 if ((ca != NULL) && (*ca == NULL)) {
96 if (!(*ca = sk_X509_new_null())) {
97 PKCS12err(PKCS12_F_PKCS12_PARSE,ERR_R_MALLOC_FAILURE);
98 return 0;
99 }
100 }
95 101
96/* Check the mac */ 102 if(pkey) *pkey = NULL;
103 if(cert) *cert = NULL;
97 104
98if (!PKCS12_verify_mac (p12, pass, -1)) { 105 /* Check the mac */
99 PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_MAC_VERIFY_FAILURE);
100 goto err;
101}
102 106
103if (!parse_pk12 (p12, pass, -1, pkey, cert, ca)) { 107 /* If password is zero length or NULL then try verifying both cases
104 PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_PARSE_ERROR); 108 * to determine which password is correct. The reason for this is that
105 goto err; 109 * under PKCS#12 password based encryption no password and a zero length
106} 110 * password are two different things...
111 */
112
113 if(!pass || !*pass) {
114 if(PKCS12_verify_mac(p12, NULL, 0)) pass = NULL;
115 else if(PKCS12_verify_mac(p12, "", 0)) pass = "";
116 else {
117 PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_MAC_VERIFY_FAILURE);
118 goto err;
119 }
120 } else if (!PKCS12_verify_mac(p12, pass, -1)) {
121 PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_MAC_VERIFY_FAILURE);
122 goto err;
123 }
107 124
108return 1; 125 if (!parse_pk12 (p12, pass, -1, pkey, cert, ca))
126 {
127 PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_PARSE_ERROR);
128 goto err;
129 }
109 130
110err: 131 return 1;
111 132
112if (pkey && *pkey) EVP_PKEY_free (*pkey); 133 err:
113if (cert && *cert) X509_free (*cert); 134
114if (ca) sk_pop_free (*ca, X509_free); 135 if (pkey && *pkey) EVP_PKEY_free(*pkey);
115return 0; 136 if (cert && *cert) X509_free(*cert);
137 if (ca) sk_X509_pop_free(*ca, X509_free);
138 return 0;
116 139
117} 140}
118 141
119/* Parse the outer PKCS#12 structure */ 142/* Parse the outer PKCS#12 structure */
120 143
121static int parse_pk12 (PKCS12 *p12, const char *pass, int passlen, 144static int parse_pk12 (PKCS12 *p12, const char *pass, int passlen,
122 EVP_PKEY **pkey, X509 **cert, STACK **ca) 145 EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca)
123{ 146{
124 STACK *asafes, *bags; 147 STACK_OF(PKCS7) *asafes;
148 STACK_OF(PKCS12_SAFEBAG) *bags;
125 int i, bagnid; 149 int i, bagnid;
126 PKCS7 *p7; 150 PKCS7 *p7;
127 ASN1_OCTET_STRING *keyid = NULL; 151 ASN1_OCTET_STRING *keyid = NULL;
152
128 char keymatch = 0; 153 char keymatch = 0;
129 if (!( asafes = M_PKCS12_unpack_authsafes (p12))) return 0; 154 if (!(asafes = PKCS12_unpack_authsafes (p12))) return 0;
130 for (i = 0; i < sk_num (asafes); i++) { 155 for (i = 0; i < sk_PKCS7_num (asafes); i++) {
131 p7 = (PKCS7 *) sk_value (asafes, i); 156 p7 = sk_PKCS7_value (asafes, i);
132 bagnid = OBJ_obj2nid (p7->type); 157 bagnid = OBJ_obj2nid (p7->type);
133 if (bagnid == NID_pkcs7_data) { 158 if (bagnid == NID_pkcs7_data) {
134 bags = M_PKCS12_unpack_p7data (p7); 159 bags = PKCS12_unpack_p7data(p7);
135 } else if (bagnid == NID_pkcs7_encrypted) { 160 } else if (bagnid == NID_pkcs7_encrypted) {
136 bags = M_PKCS12_unpack_p7encdata (p7, pass, passlen); 161 bags = PKCS12_unpack_p7encdata(p7, pass, passlen);
137 } else continue; 162 } else continue;
138 if (!bags) { 163 if (!bags) {
139 sk_pop_free (asafes, PKCS7_free); 164 sk_PKCS7_pop_free(asafes, PKCS7_free);
140 return 0; 165 return 0;
141 } 166 }
142 if (!parse_bags (bags, pass, passlen, pkey, cert, ca, 167 if (!parse_bags(bags, pass, passlen, pkey, cert, ca,
143 &keyid, &keymatch)) { 168 &keyid, &keymatch)) {
144 sk_pop_free (bags, PKCS12_SAFEBAG_free); 169 sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
145 sk_pop_free (asafes, PKCS7_free); 170 sk_PKCS7_pop_free(asafes, PKCS7_free);
146 return 0; 171 return 0;
147 } 172 }
148 sk_pop_free (bags, PKCS12_SAFEBAG_free); 173 sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
149 } 174 }
150 sk_pop_free (asafes, PKCS7_free); 175 sk_PKCS7_pop_free(asafes, PKCS7_free);
151 if (keyid) ASN1_OCTET_STRING_free (keyid); 176 if (keyid) M_ASN1_OCTET_STRING_free(keyid);
152 return 1; 177 return 1;
153} 178}
154 179
155 180
156static int parse_bags (STACK *bags, const char *pass, int passlen, 181static int parse_bags (STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass,
157 EVP_PKEY **pkey, X509 **cert, STACK **ca, 182 int passlen, EVP_PKEY **pkey, X509 **cert,
158 ASN1_OCTET_STRING **keyid, char *keymatch) 183 STACK_OF(X509) **ca, ASN1_OCTET_STRING **keyid,
184 char *keymatch)
159{ 185{
160 int i; 186 int i;
161 for (i = 0; i < sk_num (bags); i++) { 187 for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
162 if (!parse_bag ((PKCS12_SAFEBAG *)sk_value (bags, i), 188 if (!parse_bag(sk_PKCS12_SAFEBAG_value (bags, i),
163 pass, passlen, pkey, cert, ca, keyid, 189 pass, passlen, pkey, cert, ca, keyid,
164 keymatch)) return 0; 190 keymatch)) return 0;
165 } 191 }
@@ -170,26 +196,31 @@ static int parse_bags (STACK *bags, const char *pass, int passlen,
170#define MATCH_CERT 0x2 196#define MATCH_CERT 0x2
171#define MATCH_ALL 0x3 197#define MATCH_ALL 0x3
172 198
173static int parse_bag (PKCS12_SAFEBAG *bag, const char *pass, int passlen, 199static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen,
174 EVP_PKEY **pkey, X509 **cert, STACK **ca, 200 EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca,
175 ASN1_OCTET_STRING **keyid, 201 ASN1_OCTET_STRING **keyid,
176 char *keymatch) 202 char *keymatch)
177{ 203{
178 PKCS8_PRIV_KEY_INFO *p8; 204 PKCS8_PRIV_KEY_INFO *p8;
179 X509 *x509; 205 X509 *x509;
180 ASN1_OCTET_STRING *lkey = NULL; 206 ASN1_OCTET_STRING *lkey = NULL, *ckid = NULL;
181 ASN1_TYPE *attrib; 207 ASN1_TYPE *attrib;
208 ASN1_BMPSTRING *fname = NULL;
182 209
210 if ((attrib = PKCS12_get_attr (bag, NID_friendlyName)))
211 fname = attrib->value.bmpstring;
183 212
184 if ((attrib = PKCS12_get_attr (bag, NID_localKeyID))) 213 if ((attrib = PKCS12_get_attr (bag, NID_localKeyID))) {
185 lkey = attrib->value.octet_string; 214 lkey = attrib->value.octet_string;
215 ckid = lkey;
216 }
186 217
187 /* Check for any local key id matching (if needed) */ 218 /* Check for any local key id matching (if needed) */
188 if (lkey && ((*keymatch & MATCH_ALL) != MATCH_ALL)) { 219 if (lkey && ((*keymatch & MATCH_ALL) != MATCH_ALL)) {
189 if (*keyid) { 220 if (*keyid) {
190 if (ASN1_OCTET_STRING_cmp (*keyid, lkey)) lkey = NULL; 221 if (M_ASN1_OCTET_STRING_cmp(*keyid, lkey)) lkey = NULL;
191 } else { 222 } else {
192 if (!(*keyid = ASN1_OCTET_STRING_dup (lkey))) { 223 if (!(*keyid = M_ASN1_OCTET_STRING_dup(lkey))) {
193 PKCS12err(PKCS12_F_PARSE_BAGS,ERR_R_MALLOC_FAILURE); 224 PKCS12err(PKCS12_F_PARSE_BAGS,ERR_R_MALLOC_FAILURE);
194 return 0; 225 return 0;
195 } 226 }
@@ -200,16 +231,16 @@ static int parse_bag (PKCS12_SAFEBAG *bag, const char *pass, int passlen,
200 { 231 {
201 case NID_keyBag: 232 case NID_keyBag:
202 if (!lkey || !pkey) return 1; 233 if (!lkey || !pkey) return 1;
203 if (!(*pkey = EVP_PKCS82PKEY (bag->value.keybag))) return 0; 234 if (!(*pkey = EVP_PKCS82PKEY(bag->value.keybag))) return 0;
204 *keymatch |= MATCH_KEY; 235 *keymatch |= MATCH_KEY;
205 break; 236 break;
206 237
207 case NID_pkcs8ShroudedKeyBag: 238 case NID_pkcs8ShroudedKeyBag:
208 if (!lkey || !pkey) return 1; 239 if (!lkey || !pkey) return 1;
209 if (!(p8 = M_PKCS12_decrypt_skey (bag, pass, passlen))) 240 if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen)))
210 return 0; 241 return 0;
211 *pkey = EVP_PKCS82PKEY (p8); 242 *pkey = EVP_PKCS82PKEY(p8);
212 PKCS8_PRIV_KEY_INFO_free (p8); 243 PKCS8_PRIV_KEY_INFO_free(p8);
213 if (!(*pkey)) return 0; 244 if (!(*pkey)) return 0;
214 *keymatch |= MATCH_KEY; 245 *keymatch |= MATCH_KEY;
215 break; 246 break;
@@ -217,11 +248,27 @@ static int parse_bag (PKCS12_SAFEBAG *bag, const char *pass, int passlen,
217 case NID_certBag: 248 case NID_certBag:
218 if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate ) 249 if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate )
219 return 1; 250 return 1;
220 if (!(x509 = M_PKCS12_certbag2x509(bag))) return 0; 251 if (!(x509 = PKCS12_certbag2x509(bag))) return 0;
252 if(ckid) X509_keyid_set1(x509, ckid->data, ckid->length);
253 if(fname) {
254 int len;
255 unsigned char *data;
256 len = ASN1_STRING_to_UTF8(&data, fname);
257 if(len > 0) {
258 X509_alias_set1(x509, data, len);
259 OPENSSL_free(data);
260 }
261 }
262
263
221 if (lkey) { 264 if (lkey) {
222 *keymatch |= MATCH_CERT; 265 *keymatch |= MATCH_CERT;
223 if (cert) *cert = x509; 266 if (cert) *cert = x509;
224 } else if (ca) sk_push (*ca, (char *)x509); 267 else X509_free(x509);
268 } else {
269 if(ca) sk_X509_push (*ca, x509);
270 else X509_free(x509);
271 }
225 break; 272 break;
226 273
227 case NID_safeContentsBag: 274 case NID_safeContentsBag: