summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/pkcs12/p12_npas.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lib/libcrypto/pkcs12/p12_npas.c114
1 files changed, 65 insertions, 49 deletions
diff --git a/src/lib/libcrypto/pkcs12/p12_npas.c b/src/lib/libcrypto/pkcs12/p12_npas.c
index 9477de4a08..ab7bdc6458 100644
--- a/src/lib/libcrypto/pkcs12/p12_npas.c
+++ b/src/lib/libcrypto/pkcs12/p12_npas.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: p12_npas.c,v 1.8 2014/06/12 15:49:30 deraadt Exp $ */ 1/* $OpenBSD: p12_npas.c,v 1.9 2014/07/08 09:24:53 jsing Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 1999. 3 * project 1999.
4 */ 4 */
@@ -10,7 +10,7 @@
10 * are met: 10 * are met:
11 * 11 *
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 14 *
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in 16 * notice, this list of conditions and the following disclaimer in
@@ -67,32 +67,34 @@
67 67
68static int newpass_p12(PKCS12 *p12, char *oldpass, char *newpass); 68static int newpass_p12(PKCS12 *p12, char *oldpass, char *newpass);
69static int newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, char *oldpass, 69static int newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, char *oldpass,
70 char *newpass); 70 char *newpass);
71static int newpass_bag(PKCS12_SAFEBAG *bag, char *oldpass, char *newpass); 71static int newpass_bag(PKCS12_SAFEBAG *bag, char *oldpass, char *newpass);
72static int alg_get(X509_ALGOR *alg, int *pnid, int *piter, int *psaltlen); 72static int alg_get(X509_ALGOR *alg, int *pnid, int *piter, int *psaltlen);
73 73
74/* 74/*
75 * Change the password on a PKCS#12 structure. 75 * Change the password on a PKCS#12 structure.
76 */ 76 */
77 77
78int PKCS12_newpass(PKCS12 *p12, char *oldpass, char *newpass) 78int
79PKCS12_newpass(PKCS12 *p12, char *oldpass, char *newpass)
79{ 80{
80 /* Check for NULL PKCS12 structure */ 81 /* Check for NULL PKCS12 structure */
81 82
82 if(!p12) { 83 if (!p12) {
83 PKCS12err(PKCS12_F_PKCS12_NEWPASS,PKCS12_R_INVALID_NULL_PKCS12_POINTER); 84 PKCS12err(PKCS12_F_PKCS12_NEWPASS,
85 PKCS12_R_INVALID_NULL_PKCS12_POINTER);
84 return 0; 86 return 0;
85 } 87 }
86 88
87 /* Check the mac */ 89 /* Check the mac */
88 90
89 if (!PKCS12_verify_mac(p12, oldpass, -1)) { 91 if (!PKCS12_verify_mac(p12, oldpass, -1)) {
90 PKCS12err(PKCS12_F_PKCS12_NEWPASS,PKCS12_R_MAC_VERIFY_FAILURE); 92 PKCS12err(PKCS12_F_PKCS12_NEWPASS, PKCS12_R_MAC_VERIFY_FAILURE);
91 return 0; 93 return 0;
92 } 94 }
93 95
94 if (!newpass_p12(p12, oldpass, newpass)) { 96 if (!newpass_p12(p12, oldpass, newpass)) {
95 PKCS12err(PKCS12_F_PKCS12_NEWPASS,PKCS12_R_PARSE_ERROR); 97 PKCS12err(PKCS12_F_PKCS12_NEWPASS, PKCS12_R_PARSE_ERROR);
96 return 0; 98 return 0;
97 } 99 }
98 100
@@ -101,7 +103,8 @@ int PKCS12_newpass(PKCS12 *p12, char *oldpass, char *newpass)
101 103
102/* Parse the outer PKCS#12 structure */ 104/* Parse the outer PKCS#12 structure */
103 105
104static int newpass_p12(PKCS12 *p12, char *oldpass, char *newpass) 106static int
107newpass_p12(PKCS12 *p12, char *oldpass, char *newpass)
105{ 108{
106 STACK_OF(PKCS7) *asafes, *newsafes; 109 STACK_OF(PKCS7) *asafes, *newsafes;
107 STACK_OF(PKCS12_SAFEBAG) *bags; 110 STACK_OF(PKCS12_SAFEBAG) *bags;
@@ -111,8 +114,10 @@ static int newpass_p12(PKCS12 *p12, char *oldpass, char *newpass)
111 unsigned char mac[EVP_MAX_MD_SIZE]; 114 unsigned char mac[EVP_MAX_MD_SIZE];
112 unsigned int maclen; 115 unsigned int maclen;
113 116
114 if (!(asafes = PKCS12_unpack_authsafes(p12))) return 0; 117 if (!(asafes = PKCS12_unpack_authsafes(p12)))
115 if(!(newsafes = sk_PKCS7_new_null())) return 0; 118 return 0;
119 if (!(newsafes = sk_PKCS7_new_null()))
120 return 0;
116 for (i = 0; i < sk_PKCS7_num (asafes); i++) { 121 for (i = 0; i < sk_PKCS7_num (asafes); i++) {
117 p7 = sk_PKCS7_value(asafes, i); 122 p7 = sk_PKCS7_value(asafes, i);
118 bagnid = OBJ_obj2nid(p7->type); 123 bagnid = OBJ_obj2nid(p7->type);
@@ -121,28 +126,30 @@ static int newpass_p12(PKCS12 *p12, char *oldpass, char *newpass)
121 } else if (bagnid == NID_pkcs7_encrypted) { 126 } else if (bagnid == NID_pkcs7_encrypted) {
122 bags = PKCS12_unpack_p7encdata(p7, oldpass, -1); 127 bags = PKCS12_unpack_p7encdata(p7, oldpass, -1);
123 if (!alg_get(p7->d.encrypted->enc_data->algorithm, 128 if (!alg_get(p7->d.encrypted->enc_data->algorithm,
124 &pbe_nid, &pbe_iter, &pbe_saltlen)) 129 &pbe_nid, &pbe_iter, &pbe_saltlen)) {
125 {
126 sk_PKCS12_SAFEBAG_pop_free(bags, 130 sk_PKCS12_SAFEBAG_pop_free(bags,
127 PKCS12_SAFEBAG_free); 131 PKCS12_SAFEBAG_free);
128 bags = NULL; 132 bags = NULL;
129 } 133 }
130 } else continue; 134 } else
135 continue;
131 if (!bags) { 136 if (!bags) {
132 sk_PKCS7_pop_free(asafes, PKCS7_free); 137 sk_PKCS7_pop_free(asafes, PKCS7_free);
133 return 0; 138 return 0;
134 } 139 }
135 if (!newpass_bags(bags, oldpass, newpass)) { 140 if (!newpass_bags(bags, oldpass, newpass)) {
136 sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); 141 sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
137 sk_PKCS7_pop_free(asafes, PKCS7_free); 142 sk_PKCS7_pop_free(asafes, PKCS7_free);
138 return 0; 143 return 0;
139 } 144 }
140 /* Repack bag in same form with new password */ 145 /* Repack bag in same form with new password */
141 if (bagnid == NID_pkcs7_data) p7new = PKCS12_pack_p7data(bags); 146 if (bagnid == NID_pkcs7_data)
142 else p7new = PKCS12_pack_p7encdata(pbe_nid, newpass, -1, NULL, 147 p7new = PKCS12_pack_p7data(bags);
143 pbe_saltlen, pbe_iter, bags); 148 else
149 p7new = PKCS12_pack_p7encdata(pbe_nid, newpass, -1,
150 NULL, pbe_saltlen, pbe_iter, bags);
144 sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); 151 sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
145 if(!p7new) { 152 if (!p7new) {
146 sk_PKCS7_pop_free(asafes, PKCS7_free); 153 sk_PKCS7_pop_free(asafes, PKCS7_free);
147 return 0; 154 return 0;
148 } 155 }
@@ -153,73 +160,82 @@ static int newpass_p12(PKCS12 *p12, char *oldpass, char *newpass)
153 /* Repack safe: save old safe in case of error */ 160 /* Repack safe: save old safe in case of error */
154 161
155 p12_data_tmp = p12->authsafes->d.data; 162 p12_data_tmp = p12->authsafes->d.data;
156 if(!(p12->authsafes->d.data = ASN1_OCTET_STRING_new())) goto saferr; 163 if (!(p12->authsafes->d.data = ASN1_OCTET_STRING_new()))
157 if(!PKCS12_pack_authsafes(p12, newsafes)) goto saferr; 164 goto saferr;
158 165 if (!PKCS12_pack_authsafes(p12, newsafes))
159 if(!PKCS12_gen_mac(p12, newpass, -1, mac, &maclen)) goto saferr; 166 goto saferr;
160 if(!(macnew = ASN1_OCTET_STRING_new())) goto saferr; 167
161 if(!ASN1_OCTET_STRING_set(macnew, mac, maclen)) goto saferr; 168 if (!PKCS12_gen_mac(p12, newpass, -1, mac, &maclen))
169 goto saferr;
170 if (!(macnew = ASN1_OCTET_STRING_new()))
171 goto saferr;
172 if (!ASN1_OCTET_STRING_set(macnew, mac, maclen))
173 goto saferr;
162 ASN1_OCTET_STRING_free(p12->mac->dinfo->digest); 174 ASN1_OCTET_STRING_free(p12->mac->dinfo->digest);
163 p12->mac->dinfo->digest = macnew; 175 p12->mac->dinfo->digest = macnew;
164 ASN1_OCTET_STRING_free(p12_data_tmp); 176 ASN1_OCTET_STRING_free(p12_data_tmp);
165 177
166 return 1; 178 return 1;
167 179
168 saferr: 180saferr:
169 /* Restore old safe */ 181 /* Restore old safe */
170 ASN1_OCTET_STRING_free(p12->authsafes->d.data); 182 ASN1_OCTET_STRING_free(p12->authsafes->d.data);
171 ASN1_OCTET_STRING_free(macnew); 183 ASN1_OCTET_STRING_free(macnew);
172 p12->authsafes->d.data = p12_data_tmp; 184 p12->authsafes->d.data = p12_data_tmp;
173 return 0; 185 return 0;
174
175} 186}
176 187
177 188
178static int newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, char *oldpass, 189static int
179 char *newpass) 190newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, char *oldpass, char *newpass)
180{ 191{
181 int i; 192 int i;
193
182 for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) { 194 for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
183 if (!newpass_bag(sk_PKCS12_SAFEBAG_value(bags, i), 195 if (!newpass_bag(sk_PKCS12_SAFEBAG_value(bags, i),
184 oldpass, newpass)) 196 oldpass, newpass))
185 return 0; 197 return 0;
186 } 198 }
187 return 1; 199 return 1;
188} 200}
189 201
190/* Change password of safebag: only needs handle shrouded keybags */ 202/* Change password of safebag: only needs handle shrouded keybags */
191 203
192static int newpass_bag(PKCS12_SAFEBAG *bag, char *oldpass, char *newpass) 204static int
205newpass_bag(PKCS12_SAFEBAG *bag, char *oldpass, char *newpass)
193{ 206{
194 PKCS8_PRIV_KEY_INFO *p8; 207 PKCS8_PRIV_KEY_INFO *p8;
195 X509_SIG *p8new; 208 X509_SIG *p8new;
196 int p8_nid, p8_saltlen, p8_iter; 209 int p8_nid, p8_saltlen, p8_iter;
197 210
198 if(M_PKCS12_bag_type(bag) != NID_pkcs8ShroudedKeyBag) return 1; 211 if (M_PKCS12_bag_type(bag) != NID_pkcs8ShroudedKeyBag)
212 return 1;
199 213
200 if (!(p8 = PKCS8_decrypt(bag->value.shkeybag, oldpass, -1))) return 0; 214 if (!(p8 = PKCS8_decrypt(bag->value.shkeybag, oldpass, -1)))
215 return 0;
201 if (!alg_get(bag->value.shkeybag->algor, &p8_nid, &p8_iter, 216 if (!alg_get(bag->value.shkeybag->algor, &p8_nid, &p8_iter,
202 &p8_saltlen)) 217 &p8_saltlen))
203 return 0; 218 return 0;
204 if(!(p8new = PKCS8_encrypt(p8_nid, NULL, newpass, -1, NULL, p8_saltlen, 219 if (!(p8new = PKCS8_encrypt(p8_nid, NULL, newpass, -1, NULL, p8_saltlen,
205 p8_iter, p8))) return 0; 220 p8_iter, p8))) return 0;
206 X509_SIG_free(bag->value.shkeybag); 221 X509_SIG_free(bag->value.shkeybag);
207 bag->value.shkeybag = p8new; 222 bag->value.shkeybag = p8new;
208 return 1; 223 return 1;
209} 224}
210 225
211static int alg_get(X509_ALGOR *alg, int *pnid, int *piter, int *psaltlen) 226static int
227alg_get(X509_ALGOR *alg, int *pnid, int *piter, int *psaltlen)
212{ 228{
213 PBEPARAM *pbe; 229 PBEPARAM *pbe;
214 const unsigned char *p; 230 const unsigned char *p;
215 231
216 p = alg->parameter->value.sequence->data; 232 p = alg->parameter->value.sequence->data;
217 pbe = d2i_PBEPARAM(NULL, &p, alg->parameter->value.sequence->length); 233 pbe = d2i_PBEPARAM(NULL, &p, alg->parameter->value.sequence->length);
218 if (!pbe) 234 if (!pbe)
219 return 0; 235 return 0;
220 *pnid = OBJ_obj2nid(alg->algorithm); 236 *pnid = OBJ_obj2nid(alg->algorithm);
221 *piter = ASN1_INTEGER_get(pbe->iter); 237 *piter = ASN1_INTEGER_get(pbe->iter);
222 *psaltlen = pbe->salt->length; 238 *psaltlen = pbe->salt->length;
223 PBEPARAM_free(pbe); 239 PBEPARAM_free(pbe);
224 return 1; 240 return 1;
225} 241}