diff options
-rw-r--r-- | src/lib/libcrypto/pkcs12/p12_npas.c | 93 |
1 files changed, 59 insertions, 34 deletions
diff --git a/src/lib/libcrypto/pkcs12/p12_npas.c b/src/lib/libcrypto/pkcs12/p12_npas.c index 25f85d0809..6d3b43ce22 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.26 2024/01/25 14:15:05 tb Exp $ */ | 1 | /* $OpenBSD: p12_npas.c,v 1.27 2024/01/25 15:33:35 tb 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 | */ |
@@ -69,43 +69,66 @@ | |||
69 | /* PKCS#12 password change routine */ | 69 | /* PKCS#12 password change routine */ |
70 | 70 | ||
71 | static int | 71 | static int |
72 | alg_get(X509_ALGOR *alg, int *pnid, int *piter, int *psaltlen) | 72 | alg_get(X509_ALGOR *alg, int *nid, int *iter, int *salt_len) |
73 | { | 73 | { |
74 | PBEPARAM *pbe; | 74 | const ASN1_OBJECT *aobj; |
75 | const unsigned char *p; | 75 | int param_type; |
76 | 76 | const void *param; | |
77 | p = alg->parameter->value.sequence->data; | 77 | PBEPARAM *pbe = NULL; |
78 | pbe = d2i_PBEPARAM(NULL, &p, alg->parameter->value.sequence->length); | 78 | int ret = 0; |
79 | if (!pbe) | 79 | |
80 | return 0; | 80 | *nid = *iter = *salt_len = 0; |
81 | *pnid = OBJ_obj2nid(alg->algorithm); | 81 | |
82 | *piter = ASN1_INTEGER_get(pbe->iter); | 82 | X509_ALGOR_get0(&aobj, ¶m_type, ¶m, alg); |
83 | *psaltlen = pbe->salt->length; | 83 | if (param_type != V_ASN1_SEQUENCE) |
84 | goto err; | ||
85 | if ((pbe = ASN1_item_unpack(param, &PBEPARAM_it)) == NULL) | ||
86 | goto err; | ||
87 | |||
88 | /* XXX - can we validate these somehow? */ | ||
89 | *nid = OBJ_obj2nid(alg->algorithm); | ||
90 | *iter = ASN1_INTEGER_get(pbe->iter); | ||
91 | *salt_len = pbe->salt->length; | ||
92 | |||
93 | ret = 1; | ||
94 | |||
95 | err: | ||
84 | PBEPARAM_free(pbe); | 96 | PBEPARAM_free(pbe); |
85 | return 1; | 97 | |
98 | return ret; | ||
86 | } | 99 | } |
87 | 100 | ||
88 | /* Change password of safebag: only needs handle shrouded keybags */ | 101 | /* Change password of safebag: only needs handle shrouded keybags */ |
89 | static int | 102 | static int |
90 | newpass_bag(PKCS12_SAFEBAG *bag, const char *oldpass, const char *newpass) | 103 | newpass_bag(PKCS12_SAFEBAG *bag, const char *oldpass, const char *newpass) |
91 | { | 104 | { |
92 | PKCS8_PRIV_KEY_INFO *p8; | 105 | PKCS8_PRIV_KEY_INFO *p8 = NULL; |
93 | X509_SIG *p8new; | 106 | X509_SIG *keybag; |
94 | int p8_nid, p8_saltlen, p8_iter; | 107 | int nid, salt_len, iter; |
108 | int ret = 0; | ||
95 | 109 | ||
96 | if (OBJ_obj2nid(bag->type) != NID_pkcs8ShroudedKeyBag) | 110 | if (OBJ_obj2nid(bag->type) != NID_pkcs8ShroudedKeyBag) |
97 | return 1; | 111 | goto done; |
98 | 112 | ||
99 | if (!(p8 = PKCS8_decrypt(bag->value.shkeybag, oldpass, -1))) | 113 | if ((p8 = PKCS8_decrypt(bag->value.shkeybag, oldpass, -1)) == NULL) |
100 | return 0; | 114 | goto err; |
101 | if (!alg_get(bag->value.shkeybag->algor, &p8_nid, &p8_iter, | 115 | if (!alg_get(bag->value.shkeybag->algor, &nid, &iter, &salt_len)) |
102 | &p8_saltlen)) | 116 | goto err; |
103 | return 0; | 117 | |
104 | if (!(p8new = PKCS8_encrypt(p8_nid, NULL, newpass, -1, NULL, p8_saltlen, | 118 | if ((keybag = PKCS8_encrypt(nid, NULL, newpass, -1, NULL, salt_len, |
105 | p8_iter, p8))) return 0; | 119 | iter, p8)) == NULL) |
120 | goto err; | ||
121 | |||
106 | X509_SIG_free(bag->value.shkeybag); | 122 | X509_SIG_free(bag->value.shkeybag); |
107 | bag->value.shkeybag = p8new; | 123 | bag->value.shkeybag = keybag; |
108 | return 1; | 124 | |
125 | done: | ||
126 | ret = 1; | ||
127 | |||
128 | err: | ||
129 | PKCS8_PRIV_KEY_INFO_free(p8); | ||
130 | |||
131 | return ret; | ||
109 | } | 132 | } |
110 | 133 | ||
111 | static int | 134 | static int |
@@ -115,10 +138,12 @@ newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *oldpass, | |||
115 | int i; | 138 | int i; |
116 | 139 | ||
117 | for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) { | 140 | for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) { |
118 | if (!newpass_bag(sk_PKCS12_SAFEBAG_value(bags, i), | 141 | PKCS12_SAFEBAG *bag = sk_PKCS12_SAFEBAG_value(bags, i); |
119 | oldpass, newpass)) | 142 | |
143 | if (!newpass_bag(bag, oldpass, newpass)) | ||
120 | return 0; | 144 | return 0; |
121 | } | 145 | } |
146 | |||
122 | return 1; | 147 | return 1; |
123 | } | 148 | } |
124 | 149 | ||
@@ -154,19 +179,19 @@ pkcs7_repack_encdata(PKCS7 *pkcs7, STACK_OF(PKCS7) *safes, const char *oldpass, | |||
154 | const char *newpass) | 179 | const char *newpass) |
155 | { | 180 | { |
156 | STACK_OF(PKCS12_SAFEBAG) *bags; | 181 | STACK_OF(PKCS12_SAFEBAG) *bags; |
157 | int pbe_nid = 0, pbe_iter = 0, pbe_saltlen = 0; | 182 | int nid, iter, salt_len; |
158 | PKCS7 *data = NULL; | 183 | PKCS7 *data = NULL; |
159 | int ret = 0; | 184 | int ret = 0; |
160 | 185 | ||
161 | if ((bags = PKCS12_unpack_p7encdata(pkcs7, oldpass, -1)) == NULL) | 186 | if ((bags = PKCS12_unpack_p7encdata(pkcs7, oldpass, -1)) == NULL) |
162 | goto err; | 187 | goto err; |
163 | if (!alg_get(pkcs7->d.encrypted->enc_data->algorithm, &pbe_nid, | 188 | if (!alg_get(pkcs7->d.encrypted->enc_data->algorithm, &nid, |
164 | &pbe_iter, &pbe_saltlen)) | 189 | &iter, &salt_len)) |
165 | goto err; | 190 | goto err; |
166 | if (!newpass_bags(bags, oldpass, newpass)) | 191 | if (!newpass_bags(bags, oldpass, newpass)) |
167 | goto err; | 192 | goto err; |
168 | if ((data = PKCS12_pack_p7encdata(pbe_nid, newpass, -1, NULL, | 193 | if ((data = PKCS12_pack_p7encdata(nid, newpass, -1, NULL, salt_len, |
169 | pbe_saltlen, pbe_iter, bags)) == NULL) | 194 | iter, bags)) == NULL) |
170 | goto err; | 195 | goto err; |
171 | if (!sk_PKCS7_push(safes, data)) | 196 | if (!sk_PKCS7_push(safes, data)) |
172 | goto err; | 197 | goto err; |