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.c100
1 files changed, 65 insertions, 35 deletions
diff --git a/src/lib/libcrypto/pkcs12/p12_kiss.c b/src/lib/libcrypto/pkcs12/p12_kiss.c
index ee257ffbad..1fbbd6c99f 100644
--- a/src/lib/libcrypto/pkcs12/p12_kiss.c
+++ b/src/lib/libcrypto/pkcs12/p12_kiss.c
@@ -65,9 +65,10 @@
65static int parse_pk12( PKCS12 *p12, const char *pass, int passlen, 65static int parse_pk12( PKCS12 *p12, const char *pass, int passlen,
66 EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca); 66 EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca);
67 67
68static int parse_bags( STACK *bags, const char *pass, int passlen, 68static int parse_bags( STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass,
69 EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca, 69 int passlen, EVP_PKEY **pkey, X509 **cert,
70 ASN1_OCTET_STRING **keyid, char *keymatch); 70 STACK_OF(X509) **ca, ASN1_OCTET_STRING **keyid,
71 char *keymatch);
71 72
72static int parse_bag( PKCS12_SAFEBAG *bag, const char *pass, int passlen, 73static int parse_bag( PKCS12_SAFEBAG *bag, const char *pass, int passlen,
73 EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca, 74 EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca,
@@ -85,32 +86,41 @@ int PKCS12_parse (PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert,
85 86
86 /* Check for NULL PKCS12 structure */ 87 /* Check for NULL PKCS12 structure */
87 88
88 if(!p12) 89 if(!p12) {
89 {
90 PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_INVALID_NULL_PKCS12_POINTER); 90 PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_INVALID_NULL_PKCS12_POINTER);
91 return 0; 91 return 0;
92 } 92 }
93 93
94 /* Allocate stack for ca certificates if needed */ 94 /* Allocate stack for ca certificates if needed */
95 if ((ca != NULL) && (*ca == NULL)) 95 if ((ca != NULL) && (*ca == NULL)) {
96 { 96 if (!(*ca = sk_X509_new_null())) {
97 if (!(*ca = sk_X509_new(NULL)))
98 {
99 PKCS12err(PKCS12_F_PKCS12_PARSE,ERR_R_MALLOC_FAILURE); 97 PKCS12err(PKCS12_F_PKCS12_PARSE,ERR_R_MALLOC_FAILURE);
100 return 0; 98 return 0;
101 }
102 } 99 }
100 }
103 101
104 if(pkey) *pkey = NULL; 102 if(pkey) *pkey = NULL;
105 if(cert) *cert = NULL; 103 if(cert) *cert = NULL;
106 104
107 /* Check the mac */ 105 /* Check the mac */
108 106
109 if (!PKCS12_verify_mac (p12, pass, -1)) 107 /* If password is zero length or NULL then try verifying both cases
110 { 108 * to determine which password is correct. The reason for this is that
109 * under PKCS#12 password based encryption no password and a zero length
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)) {
111 PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_MAC_VERIFY_FAILURE); 121 PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_MAC_VERIFY_FAILURE);
112 goto err; 122 goto err;
113 } 123 }
114 124
115 if (!parse_pk12 (p12, pass, -1, pkey, cert, ca)) 125 if (!parse_pk12 (p12, pass, -1, pkey, cert, ca))
116 { 126 {
@@ -122,9 +132,9 @@ int PKCS12_parse (PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert,
122 132
123 err: 133 err:
124 134
125 if (pkey && *pkey) EVP_PKEY_free (*pkey); 135 if (pkey && *pkey) EVP_PKEY_free(*pkey);
126 if (cert && *cert) X509_free (*cert); 136 if (cert && *cert) X509_free(*cert);
127 if (ca) sk_X509_pop_free (*ca, X509_free); 137 if (ca) sk_X509_pop_free(*ca, X509_free);
128 return 0; 138 return 0;
129 139
130} 140}
@@ -134,45 +144,48 @@ int PKCS12_parse (PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert,
134static int parse_pk12 (PKCS12 *p12, const char *pass, int passlen, 144static int parse_pk12 (PKCS12 *p12, const char *pass, int passlen,
135 EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca) 145 EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca)
136{ 146{
137 STACK *asafes, *bags; 147 STACK_OF(PKCS7) *asafes;
148 STACK_OF(PKCS12_SAFEBAG) *bags;
138 int i, bagnid; 149 int i, bagnid;
139 PKCS7 *p7; 150 PKCS7 *p7;
140 ASN1_OCTET_STRING *keyid = NULL; 151 ASN1_OCTET_STRING *keyid = NULL;
152
141 char keymatch = 0; 153 char keymatch = 0;
142 if (!( asafes = M_PKCS12_unpack_authsafes (p12))) return 0; 154 if (!( asafes = M_PKCS12_unpack_authsafes (p12))) return 0;
143 for (i = 0; i < sk_num (asafes); i++) { 155 for (i = 0; i < sk_PKCS7_num (asafes); i++) {
144 p7 = (PKCS7 *) sk_value (asafes, i); 156 p7 = sk_PKCS7_value (asafes, i);
145 bagnid = OBJ_obj2nid (p7->type); 157 bagnid = OBJ_obj2nid (p7->type);
146 if (bagnid == NID_pkcs7_data) { 158 if (bagnid == NID_pkcs7_data) {
147 bags = M_PKCS12_unpack_p7data (p7); 159 bags = M_PKCS12_unpack_p7data(p7);
148 } else if (bagnid == NID_pkcs7_encrypted) { 160 } else if (bagnid == NID_pkcs7_encrypted) {
149 bags = M_PKCS12_unpack_p7encdata (p7, pass, passlen); 161 bags = M_PKCS12_unpack_p7encdata(p7, pass, passlen);
150 } else continue; 162 } else continue;
151 if (!bags) { 163 if (!bags) {
152 sk_pop_free (asafes, PKCS7_free); 164 sk_PKCS7_pop_free(asafes, PKCS7_free);
153 return 0; 165 return 0;
154 } 166 }
155 if (!parse_bags(bags, pass, passlen, pkey, cert, ca, 167 if (!parse_bags(bags, pass, passlen, pkey, cert, ca,
156 &keyid, &keymatch)) { 168 &keyid, &keymatch)) {
157 sk_pop_free(bags, PKCS12_SAFEBAG_free); 169 sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
158 sk_pop_free(asafes, PKCS7_free); 170 sk_PKCS7_pop_free(asafes, PKCS7_free);
159 return 0; 171 return 0;
160 } 172 }
161 sk_pop_free(bags, PKCS12_SAFEBAG_free); 173 sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
162 } 174 }
163 sk_pop_free(asafes, PKCS7_free); 175 sk_PKCS7_pop_free(asafes, PKCS7_free);
164 if (keyid) M_ASN1_OCTET_STRING_free(keyid); 176 if (keyid) M_ASN1_OCTET_STRING_free(keyid);
165 return 1; 177 return 1;
166} 178}
167 179
168 180
169static int parse_bags (STACK *bags, const char *pass, int passlen, 181static int parse_bags (STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass,
170 EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca, 182 int passlen, EVP_PKEY **pkey, X509 **cert,
171 ASN1_OCTET_STRING **keyid, char *keymatch) 183 STACK_OF(X509) **ca, ASN1_OCTET_STRING **keyid,
184 char *keymatch)
172{ 185{
173 int i; 186 int i;
174 for (i = 0; i < sk_num(bags); i++) { 187 for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
175 if (!parse_bag((PKCS12_SAFEBAG *)sk_value (bags, i), 188 if (!parse_bag(sk_PKCS12_SAFEBAG_value (bags, i),
176 pass, passlen, pkey, cert, ca, keyid, 189 pass, passlen, pkey, cert, ca, keyid,
177 keymatch)) return 0; 190 keymatch)) return 0;
178 } 191 }
@@ -190,12 +203,17 @@ static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen,
190{ 203{
191 PKCS8_PRIV_KEY_INFO *p8; 204 PKCS8_PRIV_KEY_INFO *p8;
192 X509 *x509; 205 X509 *x509;
193 ASN1_OCTET_STRING *lkey = NULL; 206 ASN1_OCTET_STRING *lkey = NULL, *ckid = NULL;
194 ASN1_TYPE *attrib; 207 ASN1_TYPE *attrib;
208 ASN1_BMPSTRING *fname = NULL;
195 209
210 if ((attrib = PKCS12_get_attr (bag, NID_friendlyName)))
211 fname = attrib->value.bmpstring;
196 212
197 if ((attrib = PKCS12_get_attr (bag, NID_localKeyID))) 213 if ((attrib = PKCS12_get_attr (bag, NID_localKeyID))) {
198 lkey = attrib->value.octet_string; 214 lkey = attrib->value.octet_string;
215 ckid = lkey;
216 }
199 217
200 /* Check for any local key id matching (if needed) */ 218 /* Check for any local key id matching (if needed) */
201 if (lkey && ((*keymatch & MATCH_ALL) != MATCH_ALL)) { 219 if (lkey && ((*keymatch & MATCH_ALL) != MATCH_ALL)) {
@@ -231,6 +249,18 @@ static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen,
231 if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate ) 249 if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate )
232 return 1; 250 return 1;
233 if (!(x509 = M_PKCS12_certbag2x509(bag))) return 0; 251 if (!(x509 = M_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
234 if (lkey) { 264 if (lkey) {
235 *keymatch |= MATCH_CERT; 265 *keymatch |= MATCH_CERT;
236 if (cert) *cert = x509; 266 if (cert) *cert = x509;