diff options
author | jsing <> | 2019-11-01 03:45:13 +0000 |
---|---|---|
committer | jsing <> | 2019-11-01 03:45:13 +0000 |
commit | 06b54e9217af744c680ff812191733948cfafa40 (patch) | |
tree | 76c7f4e1cab4725386517c297aacf6d5616d0c59 /src/lib | |
parent | 207d5072457060a56e0ae65ce9e652e88178d798 (diff) | |
download | openbsd-06b54e9217af744c680ff812191733948cfafa40.tar.gz openbsd-06b54e9217af744c680ff812191733948cfafa40.tar.bz2 openbsd-06b54e9217af744c680ff812191733948cfafa40.zip |
Update RSA ASN.1 code to handle RSA-PSS.
From OpenSSL 1.1.1d.
ok tb@
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/libcrypto/rsa/rsa.h | 3 | ||||
-rw-r--r-- | src/lib/libcrypto/rsa/rsa_ameth.c | 679 | ||||
-rw-r--r-- | src/lib/libcrypto/rsa/rsa_err.c | 3 | ||||
-rw-r--r-- | src/lib/libcrypto/rsa/rsa_locl.h | 6 |
4 files changed, 389 insertions, 302 deletions
diff --git a/src/lib/libcrypto/rsa/rsa.h b/src/lib/libcrypto/rsa/rsa.h index 48d6d64bd1..86e5f8e20f 100644 --- a/src/lib/libcrypto/rsa/rsa.h +++ b/src/lib/libcrypto/rsa/rsa.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: rsa.h,v 1.45 2019/10/31 13:56:29 jsing Exp $ */ | 1 | /* $OpenBSD: rsa.h,v 1.46 2019/11/01 03:45:13 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -615,6 +615,7 @@ void ERR_load_RSA_strings(void); | |||
615 | #define RSA_R_DATA_TOO_LARGE_FOR_MODULUS 132 | 615 | #define RSA_R_DATA_TOO_LARGE_FOR_MODULUS 132 |
616 | #define RSA_R_DATA_TOO_SMALL 111 | 616 | #define RSA_R_DATA_TOO_SMALL 111 |
617 | #define RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE 122 | 617 | #define RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE 122 |
618 | #define RSA_R_DIGEST_DOES_NOT_MATCH 158 | ||
618 | #define RSA_R_DIGEST_NOT_ALLOWED 145 | 619 | #define RSA_R_DIGEST_NOT_ALLOWED 145 |
619 | #define RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY 112 | 620 | #define RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY 112 |
620 | #define RSA_R_DMP1_NOT_CONGRUENT_TO_D 124 | 621 | #define RSA_R_DMP1_NOT_CONGRUENT_TO_D 124 |
diff --git a/src/lib/libcrypto/rsa/rsa_ameth.c b/src/lib/libcrypto/rsa/rsa_ameth.c index f71cee8ec1..d23848d0d5 100644 --- a/src/lib/libcrypto/rsa/rsa_ameth.c +++ b/src/lib/libcrypto/rsa/rsa_ameth.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: rsa_ameth.c,v 1.20 2019/10/31 13:56:29 jsing Exp $ */ | 1 | /* $OpenBSD: rsa_ameth.c,v 1.21 2019/11/01 03:45:13 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 2006. | 3 | * project 2006. |
4 | */ | 4 | */ |
@@ -66,23 +66,81 @@ | |||
66 | #include <openssl/rsa.h> | 66 | #include <openssl/rsa.h> |
67 | #include <openssl/x509.h> | 67 | #include <openssl/x509.h> |
68 | 68 | ||
69 | |||
70 | #include "asn1_locl.h" | 69 | #include "asn1_locl.h" |
70 | #include "rsa_locl.h" | ||
71 | |||
72 | static RSA_PSS_PARAMS *rsa_pss_decode(const X509_ALGOR *alg); | ||
73 | |||
74 | /* Set any parameters associated with pkey */ | ||
75 | static int | ||
76 | rsa_param_encode(const EVP_PKEY *pkey, ASN1_STRING **pstr, int *pstrtype) | ||
77 | { | ||
78 | const RSA *rsa = pkey->pkey.rsa; | ||
79 | |||
80 | *pstr = NULL; | ||
81 | |||
82 | /* If RSA it's just NULL type */ | ||
83 | if (pkey->ameth->pkey_id != EVP_PKEY_RSA_PSS) { | ||
84 | *pstrtype = V_ASN1_NULL; | ||
85 | return 1; | ||
86 | } | ||
87 | |||
88 | /* If no PSS parameters we omit parameters entirely */ | ||
89 | if (rsa->pss == NULL) { | ||
90 | *pstrtype = V_ASN1_UNDEF; | ||
91 | return 1; | ||
92 | } | ||
93 | |||
94 | /* Encode PSS parameters */ | ||
95 | if (ASN1_item_pack(rsa->pss, &RSA_PSS_PARAMS_it, pstr) == NULL) | ||
96 | return 0; | ||
97 | |||
98 | *pstrtype = V_ASN1_SEQUENCE; | ||
99 | return 1; | ||
100 | } | ||
101 | |||
102 | /* Decode any parameters and set them in RSA structure */ | ||
103 | static int | ||
104 | rsa_param_decode(RSA *rsa, const X509_ALGOR *alg) | ||
105 | { | ||
106 | const ASN1_OBJECT *algoid; | ||
107 | const void *algp; | ||
108 | int algptype; | ||
109 | |||
110 | X509_ALGOR_get0(&algoid, &algptype, &algp, alg); | ||
111 | if (OBJ_obj2nid(algoid) != EVP_PKEY_RSA_PSS) | ||
112 | return 1; | ||
113 | if (algptype == V_ASN1_UNDEF) | ||
114 | return 1; | ||
115 | if (algptype != V_ASN1_SEQUENCE) { | ||
116 | RSAerror(RSA_R_INVALID_PSS_PARAMETERS); | ||
117 | return 0; | ||
118 | } | ||
119 | rsa->pss = rsa_pss_decode(alg); | ||
120 | if (rsa->pss == NULL) | ||
121 | return 0; | ||
122 | return 1; | ||
123 | } | ||
71 | 124 | ||
72 | static int | 125 | static int |
73 | rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) | 126 | rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) |
74 | { | 127 | { |
75 | unsigned char *penc = NULL; | 128 | unsigned char *penc = NULL; |
76 | int penclen; | 129 | int penclen; |
130 | ASN1_STRING *str; | ||
131 | int strtype; | ||
77 | 132 | ||
133 | if (!rsa_param_encode(pkey, &str, &strtype)) | ||
134 | return 0; | ||
78 | penclen = i2d_RSAPublicKey(pkey->pkey.rsa, &penc); | 135 | penclen = i2d_RSAPublicKey(pkey->pkey.rsa, &penc); |
79 | if (penclen <= 0) | 136 | if (penclen <= 0) |
80 | return 0; | 137 | return 0; |
81 | if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_RSA), | 138 | if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(pkey->ameth->pkey_id), |
82 | V_ASN1_NULL, NULL, penc, penclen)) | 139 | strtype, str, penc, penclen)) |
83 | return 1; | 140 | return 1; |
84 | 141 | ||
85 | free(penc); | 142 | free(penc); |
143 | |||
86 | return 0; | 144 | return 0; |
87 | } | 145 | } |
88 | 146 | ||
@@ -91,15 +149,23 @@ rsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) | |||
91 | { | 149 | { |
92 | const unsigned char *p; | 150 | const unsigned char *p; |
93 | int pklen; | 151 | int pklen; |
152 | X509_ALGOR *alg; | ||
94 | RSA *rsa = NULL; | 153 | RSA *rsa = NULL; |
95 | 154 | ||
96 | if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, NULL, pubkey)) | 155 | if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &alg, pubkey)) |
97 | return 0; | 156 | return 0; |
98 | if (!(rsa = d2i_RSAPublicKey(NULL, &p, pklen))) { | 157 | if ((rsa = d2i_RSAPublicKey(NULL, &p, pklen)) == NULL) { |
99 | RSAerror(ERR_R_RSA_LIB); | 158 | RSAerror(ERR_R_RSA_LIB); |
100 | return 0; | 159 | return 0; |
101 | } | 160 | } |
102 | EVP_PKEY_assign_RSA (pkey, rsa); | 161 | if (!rsa_param_decode(rsa, alg)) { |
162 | RSA_free(rsa); | ||
163 | return 0; | ||
164 | } | ||
165 | if (!EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, rsa)) { | ||
166 | RSA_free(rsa); | ||
167 | return 0; | ||
168 | } | ||
103 | return 1; | 169 | return 1; |
104 | } | 170 | } |
105 | 171 | ||
@@ -109,6 +175,7 @@ rsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) | |||
109 | if (BN_cmp(b->pkey.rsa->n, a->pkey.rsa->n) != 0 || | 175 | if (BN_cmp(b->pkey.rsa->n, a->pkey.rsa->n) != 0 || |
110 | BN_cmp(b->pkey.rsa->e, a->pkey.rsa->e) != 0) | 176 | BN_cmp(b->pkey.rsa->e, a->pkey.rsa->e) != 0) |
111 | return 0; | 177 | return 0; |
178 | |||
112 | return 1; | 179 | return 1; |
113 | } | 180 | } |
114 | 181 | ||
@@ -117,11 +184,11 @@ old_rsa_priv_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen) | |||
117 | { | 184 | { |
118 | RSA *rsa; | 185 | RSA *rsa; |
119 | 186 | ||
120 | if (!(rsa = d2i_RSAPrivateKey (NULL, pder, derlen))) { | 187 | if ((rsa = d2i_RSAPrivateKey(NULL, pder, derlen)) == NULL) { |
121 | RSAerror(ERR_R_RSA_LIB); | 188 | RSAerror(ERR_R_RSA_LIB); |
122 | return 0; | 189 | return 0; |
123 | } | 190 | } |
124 | EVP_PKEY_assign_RSA(pkey, rsa); | 191 | EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, rsa); |
125 | return 1; | 192 | return 1; |
126 | } | 193 | } |
127 | 194 | ||
@@ -136,17 +203,23 @@ rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) | |||
136 | { | 203 | { |
137 | unsigned char *rk = NULL; | 204 | unsigned char *rk = NULL; |
138 | int rklen; | 205 | int rklen; |
206 | ASN1_STRING *str; | ||
207 | int strtype; | ||
139 | 208 | ||
140 | rklen = i2d_RSAPrivateKey(pkey->pkey.rsa, &rk); | 209 | if (!rsa_param_encode(pkey, &str, &strtype)) |
210 | return 0; | ||
141 | 211 | ||
212 | rklen = i2d_RSAPrivateKey(pkey->pkey.rsa, &rk); | ||
142 | if (rklen <= 0) { | 213 | if (rklen <= 0) { |
143 | RSAerror(ERR_R_MALLOC_FAILURE); | 214 | RSAerror(ERR_R_MALLOC_FAILURE); |
215 | ASN1_STRING_free(str); | ||
144 | return 0; | 216 | return 0; |
145 | } | 217 | } |
146 | 218 | ||
147 | if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_rsaEncryption), 0, | 219 | if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(pkey->ameth->pkey_id), 0, |
148 | V_ASN1_NULL, NULL, rk, rklen)) { | 220 | strtype, str, rk, rklen)) { |
149 | RSAerror(ERR_R_MALLOC_FAILURE); | 221 | RSAerror(ERR_R_MALLOC_FAILURE); |
222 | ASN1_STRING_free(str); | ||
150 | return 0; | 223 | return 0; |
151 | } | 224 | } |
152 | 225 | ||
@@ -157,11 +230,24 @@ static int | |||
157 | rsa_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8) | 230 | rsa_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8) |
158 | { | 231 | { |
159 | const unsigned char *p; | 232 | const unsigned char *p; |
233 | RSA *rsa; | ||
160 | int pklen; | 234 | int pklen; |
235 | const X509_ALGOR *alg; | ||
161 | 236 | ||
162 | if (!PKCS8_pkey_get0(NULL, &p, &pklen, NULL, p8)) | 237 | if (!PKCS8_pkey_get0(NULL, &p, &pklen, &alg, p8)) |
238 | return 0; | ||
239 | rsa = d2i_RSAPrivateKey(NULL, &p, pklen); | ||
240 | if (rsa == NULL) { | ||
241 | RSAerror(ERR_R_RSA_LIB); | ||
242 | return 0; | ||
243 | } | ||
244 | if (!rsa_param_decode(rsa, alg)) { | ||
245 | RSA_free(rsa); | ||
163 | return 0; | 246 | return 0; |
164 | return old_rsa_priv_decode(pkey, &p, pklen); | 247 | } |
248 | EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, rsa); | ||
249 | |||
250 | return 1; | ||
165 | } | 251 | } |
166 | 252 | ||
167 | static int | 253 | static int |
@@ -182,123 +268,29 @@ int_rsa_free(EVP_PKEY *pkey) | |||
182 | RSA_free(pkey->pkey.rsa); | 268 | RSA_free(pkey->pkey.rsa); |
183 | } | 269 | } |
184 | 270 | ||
185 | static void | 271 | static X509_ALGOR * |
186 | update_buflen(const BIGNUM *b, size_t *pbuflen) | 272 | rsa_mgf1_decode(X509_ALGOR *alg) |
187 | { | ||
188 | size_t i; | ||
189 | |||
190 | if (!b) | ||
191 | return; | ||
192 | if (*pbuflen < (i = (size_t)BN_num_bytes(b))) | ||
193 | *pbuflen = i; | ||
194 | } | ||
195 | |||
196 | static int | ||
197 | do_rsa_print(BIO *bp, const RSA *x, int off, int priv) | ||
198 | { | ||
199 | char *str; | ||
200 | const char *s; | ||
201 | unsigned char *m = NULL; | ||
202 | int ret = 0, mod_len = 0; | ||
203 | size_t buf_len = 0; | ||
204 | |||
205 | update_buflen(x->n, &buf_len); | ||
206 | update_buflen(x->e, &buf_len); | ||
207 | |||
208 | if (priv) { | ||
209 | update_buflen(x->d, &buf_len); | ||
210 | update_buflen(x->p, &buf_len); | ||
211 | update_buflen(x->q, &buf_len); | ||
212 | update_buflen(x->dmp1, &buf_len); | ||
213 | update_buflen(x->dmq1, &buf_len); | ||
214 | update_buflen(x->iqmp, &buf_len); | ||
215 | } | ||
216 | |||
217 | m = malloc(buf_len + 10); | ||
218 | if (m == NULL) { | ||
219 | RSAerror(ERR_R_MALLOC_FAILURE); | ||
220 | goto err; | ||
221 | } | ||
222 | |||
223 | if (x->n != NULL) | ||
224 | mod_len = BN_num_bits(x->n); | ||
225 | |||
226 | if (!BIO_indent(bp, off, 128)) | ||
227 | goto err; | ||
228 | |||
229 | if (priv && x->d) { | ||
230 | if (BIO_printf(bp, "Private-Key: (%d bit)\n", mod_len) <= 0) | ||
231 | goto err; | ||
232 | str = "modulus:"; | ||
233 | s = "publicExponent:"; | ||
234 | } else { | ||
235 | if (BIO_printf(bp, "Public-Key: (%d bit)\n", mod_len) <= 0) | ||
236 | goto err; | ||
237 | str = "Modulus:"; | ||
238 | s= "Exponent:"; | ||
239 | } | ||
240 | if (!ASN1_bn_print(bp, str, x->n, m, off)) | ||
241 | goto err; | ||
242 | if (!ASN1_bn_print(bp, s, x->e, m, off)) | ||
243 | goto err; | ||
244 | if (priv) { | ||
245 | if (!ASN1_bn_print(bp, "privateExponent:", x->d,m, off)) | ||
246 | goto err; | ||
247 | if (!ASN1_bn_print(bp, "prime1:", x->p, m, off)) | ||
248 | goto err; | ||
249 | if (!ASN1_bn_print(bp, "prime2:", x->q, m, off)) | ||
250 | goto err; | ||
251 | if (!ASN1_bn_print(bp, "exponent1:", x->dmp1, m, off)) | ||
252 | goto err; | ||
253 | if (!ASN1_bn_print(bp, "exponent2:", x->dmq1, m, off)) | ||
254 | goto err; | ||
255 | if (!ASN1_bn_print(bp, "coefficient:", x->iqmp, m, off)) | ||
256 | goto err; | ||
257 | } | ||
258 | ret = 1; | ||
259 | err: | ||
260 | free(m); | ||
261 | return (ret); | ||
262 | } | ||
263 | |||
264 | static int | ||
265 | rsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx) | ||
266 | { | 273 | { |
267 | return do_rsa_print(bp, pkey->pkey.rsa, indent, 0); | 274 | if (OBJ_obj2nid(alg->algorithm) != NID_mgf1) |
268 | } | 275 | return NULL; |
269 | 276 | ||
270 | static int | 277 | return ASN1_TYPE_unpack_sequence(&X509_ALGOR_it, alg->parameter); |
271 | rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx) | ||
272 | { | ||
273 | return do_rsa_print(bp, pkey->pkey.rsa, indent, 1); | ||
274 | } | 278 | } |
275 | 279 | ||
276 | static RSA_PSS_PARAMS * | 280 | static RSA_PSS_PARAMS * |
277 | rsa_pss_decode(const X509_ALGOR *alg, X509_ALGOR **pmaskHash) | 281 | rsa_pss_decode(const X509_ALGOR *alg) |
278 | { | 282 | { |
279 | const unsigned char *p; | ||
280 | int plen; | ||
281 | RSA_PSS_PARAMS *pss; | 283 | RSA_PSS_PARAMS *pss; |
282 | 284 | ||
283 | *pmaskHash = NULL; | 285 | pss = ASN1_TYPE_unpack_sequence(&RSA_PSS_PARAMS_it, alg->parameter); |
284 | 286 | if (pss == NULL) | |
285 | if (!alg->parameter || alg->parameter->type != V_ASN1_SEQUENCE) | ||
286 | return NULL; | ||
287 | |||
288 | p = alg->parameter->value.sequence->data; | ||
289 | plen = alg->parameter->value.sequence->length; | ||
290 | pss = d2i_RSA_PSS_PARAMS(NULL, &p, plen); | ||
291 | |||
292 | if (!pss) | ||
293 | return NULL; | 287 | return NULL; |
294 | 288 | ||
295 | if (pss->maskGenAlgorithm) { | 289 | if (pss->maskGenAlgorithm != NULL) { |
296 | ASN1_TYPE *param = pss->maskGenAlgorithm->parameter; | 290 | pss->maskHash = rsa_mgf1_decode(pss->maskGenAlgorithm); |
297 | if (OBJ_obj2nid(pss->maskGenAlgorithm->algorithm) == NID_mgf1 && | 291 | if (pss->maskHash == NULL) { |
298 | param && param->type == V_ASN1_SEQUENCE) { | 292 | RSA_PSS_PARAMS_free(pss); |
299 | p = param->value.sequence->data; | 293 | return NULL; |
300 | plen = param->value.sequence->length; | ||
301 | *pmaskHash = d2i_X509_ALGOR(NULL, &p, plen); | ||
302 | } | 294 | } |
303 | } | 295 | } |
304 | 296 | ||
@@ -306,18 +298,31 @@ rsa_pss_decode(const X509_ALGOR *alg, X509_ALGOR **pmaskHash) | |||
306 | } | 298 | } |
307 | 299 | ||
308 | static int | 300 | static int |
309 | rsa_pss_param_print(BIO *bp, RSA_PSS_PARAMS *pss, X509_ALGOR *maskHash, | 301 | rsa_pss_param_print(BIO *bp, int pss_key, RSA_PSS_PARAMS *pss, int indent) |
310 | int indent) | ||
311 | { | 302 | { |
312 | int rv = 0; | 303 | int rv = 0; |
304 | X509_ALGOR *maskHash = NULL; | ||
313 | 305 | ||
314 | if (!pss) { | 306 | if (!BIO_indent(bp, indent, 128)) |
315 | if (BIO_puts(bp, " (INVALID PSS PARAMETERS)\n") <= 0) | 307 | goto err; |
308 | if (pss_key) { | ||
309 | if (pss == NULL) { | ||
310 | if (BIO_puts(bp, "No PSS parameter restrictions\n") <= 0) | ||
311 | return 0; | ||
312 | return 1; | ||
313 | } else { | ||
314 | if (BIO_puts(bp, "PSS parameter restrictions:") <= 0) | ||
315 | return 0; | ||
316 | } | ||
317 | } else if (pss == NULL) { | ||
318 | if (BIO_puts(bp,"(INVALID PSS PARAMETERS)\n") <= 0) | ||
316 | return 0; | 319 | return 0; |
317 | return 1; | 320 | return 1; |
318 | } | 321 | } |
319 | if (BIO_puts(bp, "\n") <= 0) | 322 | if (BIO_puts(bp, "\n") <= 0) |
320 | goto err; | 323 | goto err; |
324 | if (pss_key) | ||
325 | indent += 2; | ||
321 | if (!BIO_indent(bp, indent, 128)) | 326 | if (!BIO_indent(bp, indent, 128)) |
322 | goto err; | 327 | goto err; |
323 | if (BIO_puts(bp, "Hash Algorithm: ") <= 0) | 328 | if (BIO_puts(bp, "Hash Algorithm: ") <= 0) |
@@ -326,8 +331,9 @@ rsa_pss_param_print(BIO *bp, RSA_PSS_PARAMS *pss, X509_ALGOR *maskHash, | |||
326 | if (pss->hashAlgorithm) { | 331 | if (pss->hashAlgorithm) { |
327 | if (i2a_ASN1_OBJECT(bp, pss->hashAlgorithm->algorithm) <= 0) | 332 | if (i2a_ASN1_OBJECT(bp, pss->hashAlgorithm->algorithm) <= 0) |
328 | goto err; | 333 | goto err; |
329 | } else if (BIO_puts(bp, "sha1 (default)") <= 0) | 334 | } else if (BIO_puts(bp, "sha1 (default)") <= 0) { |
330 | goto err; | 335 | goto err; |
336 | } | ||
331 | 337 | ||
332 | if (BIO_puts(bp, "\n") <= 0) | 338 | if (BIO_puts(bp, "\n") <= 0) |
333 | goto err; | 339 | goto err; |
@@ -342,24 +348,28 @@ rsa_pss_param_print(BIO *bp, RSA_PSS_PARAMS *pss, X509_ALGOR *maskHash, | |||
342 | goto err; | 348 | goto err; |
343 | if (BIO_puts(bp, " with ") <= 0) | 349 | if (BIO_puts(bp, " with ") <= 0) |
344 | goto err; | 350 | goto err; |
345 | if (maskHash) { | 351 | maskHash = rsa_mgf1_decode(pss->maskGenAlgorithm); |
352 | if (maskHash != NULL) { | ||
346 | if (i2a_ASN1_OBJECT(bp, maskHash->algorithm) <= 0) | 353 | if (i2a_ASN1_OBJECT(bp, maskHash->algorithm) <= 0) |
347 | goto err; | 354 | goto err; |
348 | } else if (BIO_puts(bp, "INVALID") <= 0) | 355 | } else if (BIO_puts(bp, "INVALID") <= 0) { |
349 | goto err; | 356 | goto err; |
350 | } else if (BIO_puts(bp, "mgf1 with sha1 (default)") <= 0) | 357 | } |
358 | } else if (BIO_puts(bp, "mgf1 with sha1 (default)") <= 0) { | ||
351 | goto err; | 359 | goto err; |
360 | } | ||
352 | BIO_puts(bp, "\n"); | 361 | BIO_puts(bp, "\n"); |
353 | 362 | ||
354 | if (!BIO_indent(bp, indent, 128)) | 363 | if (!BIO_indent(bp, indent, 128)) |
355 | goto err; | 364 | goto err; |
356 | if (BIO_puts(bp, "Salt Length: 0x") <= 0) | 365 | if (BIO_printf(bp, "%s Salt Length: 0x", pss_key ? "Minimum" : "") <= 0) |
357 | goto err; | 366 | goto err; |
358 | if (pss->saltLength) { | 367 | if (pss->saltLength) { |
359 | if (i2a_ASN1_INTEGER(bp, pss->saltLength) <= 0) | 368 | if (i2a_ASN1_INTEGER(bp, pss->saltLength) <= 0) |
360 | goto err; | 369 | goto err; |
361 | } else if (BIO_puts(bp, "14 (default)") <= 0) | 370 | } else if (BIO_puts(bp, "14 (default)") <= 0) { |
362 | goto err; | 371 | goto err; |
372 | } | ||
363 | BIO_puts(bp, "\n"); | 373 | BIO_puts(bp, "\n"); |
364 | 374 | ||
365 | if (!BIO_indent(bp, indent, 128)) | 375 | if (!BIO_indent(bp, indent, 128)) |
@@ -369,34 +379,92 @@ rsa_pss_param_print(BIO *bp, RSA_PSS_PARAMS *pss, X509_ALGOR *maskHash, | |||
369 | if (pss->trailerField) { | 379 | if (pss->trailerField) { |
370 | if (i2a_ASN1_INTEGER(bp, pss->trailerField) <= 0) | 380 | if (i2a_ASN1_INTEGER(bp, pss->trailerField) <= 0) |
371 | goto err; | 381 | goto err; |
372 | } else if (BIO_puts(bp, "BC (default)") <= 0) | 382 | } else if (BIO_puts(bp, "BC (default)") <= 0) { |
373 | goto err; | 383 | goto err; |
384 | } | ||
374 | BIO_puts(bp, "\n"); | 385 | BIO_puts(bp, "\n"); |
375 | 386 | ||
376 | rv = 1; | 387 | rv = 1; |
377 | 388 | ||
378 | err: | 389 | err: |
390 | X509_ALGOR_free(maskHash); | ||
379 | return rv; | 391 | return rv; |
392 | |||
393 | } | ||
394 | |||
395 | static int | ||
396 | pkey_rsa_print(BIO *bp, const EVP_PKEY *pkey, int off, int priv) | ||
397 | { | ||
398 | const RSA *x = pkey->pkey.rsa; | ||
399 | char *str; | ||
400 | const char *s; | ||
401 | int ret = 0, mod_len = 0; | ||
402 | |||
403 | if (x->n != NULL) | ||
404 | mod_len = BN_num_bits(x->n); | ||
405 | |||
406 | if (!BIO_indent(bp, off, 128)) | ||
407 | goto err; | ||
408 | |||
409 | if (BIO_printf(bp, "%s ", pkey_is_pss(pkey) ? "RSA-PSS" : "RSA") <= 0) | ||
410 | goto err; | ||
411 | |||
412 | if (BIO_printf(bp, "Public-Key: (%d bit)\n", mod_len) <= 0) | ||
413 | goto err; | ||
414 | str = "Modulus:"; | ||
415 | s = "Exponent:"; | ||
416 | if (!ASN1_bn_print(bp, str, x->n, NULL, off)) | ||
417 | goto err; | ||
418 | if (!ASN1_bn_print(bp, s, x->e, NULL, off)) | ||
419 | goto err; | ||
420 | if (priv) { | ||
421 | if (!ASN1_bn_print(bp, "privateExponent:", x->d, NULL, off)) | ||
422 | goto err; | ||
423 | if (!ASN1_bn_print(bp, "prime1:", x->p, NULL, off)) | ||
424 | goto err; | ||
425 | if (!ASN1_bn_print(bp, "prime2:", x->q, NULL, off)) | ||
426 | goto err; | ||
427 | if (!ASN1_bn_print(bp, "exponent1:", x->dmp1, NULL, off)) | ||
428 | goto err; | ||
429 | if (!ASN1_bn_print(bp, "exponent2:", x->dmq1, NULL, off)) | ||
430 | goto err; | ||
431 | if (!ASN1_bn_print(bp, "coefficient:", x->iqmp, NULL, off)) | ||
432 | goto err; | ||
433 | } | ||
434 | if (pkey_is_pss(pkey) && !rsa_pss_param_print(bp, 1, x->pss, off)) | ||
435 | goto err; | ||
436 | ret = 1; | ||
437 | err: | ||
438 | return ret; | ||
439 | } | ||
440 | |||
441 | static int | ||
442 | rsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx) | ||
443 | { | ||
444 | return pkey_rsa_print(bp, pkey, indent, 0); | ||
445 | } | ||
446 | |||
447 | static int | ||
448 | rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, ASN1_PCTX *ctx) | ||
449 | { | ||
450 | return pkey_rsa_print(bp, pkey, indent, 1); | ||
380 | } | 451 | } |
381 | 452 | ||
382 | static int | 453 | static int |
383 | rsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, const ASN1_STRING *sig, | 454 | rsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, const ASN1_STRING *sig, |
384 | int indent, ASN1_PCTX *pctx) | 455 | int indent, ASN1_PCTX *pctx) |
385 | { | 456 | { |
386 | if (OBJ_obj2nid(sigalg->algorithm) == NID_rsassaPss) { | 457 | if (OBJ_obj2nid(sigalg->algorithm) == EVP_PKEY_RSA_PSS) { |
387 | int rv; | 458 | int rv; |
388 | RSA_PSS_PARAMS *pss; | 459 | RSA_PSS_PARAMS *pss = rsa_pss_decode(sigalg); |
389 | X509_ALGOR *maskHash; | 460 | |
390 | pss = rsa_pss_decode(sigalg, &maskHash); | 461 | rv = rsa_pss_param_print(bp, 0, pss, indent); |
391 | rv = rsa_pss_param_print(bp, pss, maskHash, indent); | 462 | RSA_PSS_PARAMS_free(pss); |
392 | if (pss) | ||
393 | RSA_PSS_PARAMS_free(pss); | ||
394 | if (maskHash) | ||
395 | X509_ALGOR_free(maskHash); | ||
396 | if (!rv) | 463 | if (!rv) |
397 | return 0; | 464 | return 0; |
398 | } else if (!sig && BIO_puts(bp, "\n") <= 0) | 465 | } else if (!sig && BIO_puts(bp, "\n") <= 0) { |
399 | return 0; | 466 | return 0; |
467 | } | ||
400 | if (sig) | 468 | if (sig) |
401 | return X509_signature_dump(bp, sig, indent); | 469 | return X509_signature_dump(bp, sig, indent); |
402 | return 1; | 470 | return 1; |
@@ -406,6 +474,9 @@ static int | |||
406 | rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) | 474 | rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) |
407 | { | 475 | { |
408 | X509_ALGOR *alg = NULL; | 476 | X509_ALGOR *alg = NULL; |
477 | const EVP_MD *md; | ||
478 | const EVP_MD *mgf1md; | ||
479 | int min_saltlen; | ||
409 | 480 | ||
410 | switch (op) { | 481 | switch (op) { |
411 | case ASN1_PKEY_CTRL_PKCS7_SIGN: | 482 | case ASN1_PKEY_CTRL_PKCS7_SIGN: |
@@ -414,12 +485,24 @@ rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) | |||
414 | break; | 485 | break; |
415 | 486 | ||
416 | case ASN1_PKEY_CTRL_PKCS7_ENCRYPT: | 487 | case ASN1_PKEY_CTRL_PKCS7_ENCRYPT: |
488 | if (pkey_is_pss(pkey)) | ||
489 | return -2; | ||
417 | if (arg1 == 0) | 490 | if (arg1 == 0) |
418 | PKCS7_RECIP_INFO_get0_alg(arg2, &alg); | 491 | PKCS7_RECIP_INFO_get0_alg(arg2, &alg); |
419 | break; | 492 | break; |
420 | 493 | ||
421 | case ASN1_PKEY_CTRL_DEFAULT_MD_NID: | 494 | case ASN1_PKEY_CTRL_DEFAULT_MD_NID: |
422 | *(int *)arg2 = NID_sha1; | 495 | if (pkey->pkey.rsa->pss != NULL) { |
496 | if (!rsa_pss_get_param(pkey->pkey.rsa->pss, &md, &mgf1md, | ||
497 | &min_saltlen)) { | ||
498 | RSAerror(ERR_R_INTERNAL_ERROR); | ||
499 | return 0; | ||
500 | } | ||
501 | *(int *)arg2 = EVP_MD_type(md); | ||
502 | /* Return of 2 indicates this MD is mandatory */ | ||
503 | return 2; | ||
504 | } | ||
505 | *(int *)arg2 = NID_sha256; | ||
423 | return 1; | 506 | return 1; |
424 | 507 | ||
425 | default: | 508 | default: |
@@ -488,7 +571,36 @@ rsa_algor_to_md(X509_ALGOR *alg) | |||
488 | return md; | 571 | return md; |
489 | } | 572 | } |
490 | 573 | ||
491 | /* convert algorithm ID to EVP_MD, default SHA1 */ | 574 | /* |
575 | * Convert EVP_PKEY_CTX in PSS mode into corresponding algorithm parameter, | ||
576 | * suitable for setting an AlgorithmIdentifier. | ||
577 | */ | ||
578 | static RSA_PSS_PARAMS * | ||
579 | rsa_ctx_to_pss(EVP_PKEY_CTX *pkctx) | ||
580 | { | ||
581 | const EVP_MD *sigmd, *mgf1md; | ||
582 | EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(pkctx); | ||
583 | int saltlen; | ||
584 | |||
585 | if (EVP_PKEY_CTX_get_signature_md(pkctx, &sigmd) <= 0) | ||
586 | return NULL; | ||
587 | if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0) | ||
588 | return NULL; | ||
589 | if (!EVP_PKEY_CTX_get_rsa_pss_saltlen(pkctx, &saltlen)) | ||
590 | return NULL; | ||
591 | if (saltlen == -1) { | ||
592 | saltlen = EVP_MD_size(sigmd); | ||
593 | } else if (saltlen == -2 || saltlen == -3) { | ||
594 | saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2; | ||
595 | if ((EVP_PKEY_bits(pk) & 0x7) == 1) | ||
596 | saltlen--; | ||
597 | if (saltlen < 0) | ||
598 | return NULL; | ||
599 | } | ||
600 | |||
601 | return rsa_pss_params_create(sigmd, mgf1md, saltlen); | ||
602 | } | ||
603 | |||
492 | RSA_PSS_PARAMS * | 604 | RSA_PSS_PARAMS * |
493 | rsa_pss_params_create(const EVP_MD *sigmd, const EVP_MD *mgf1md, int saltlen) | 605 | rsa_pss_params_create(const EVP_MD *sigmd, const EVP_MD *mgf1md, int saltlen) |
494 | { | 606 | { |
@@ -517,6 +629,78 @@ rsa_pss_params_create(const EVP_MD *sigmd, const EVP_MD *mgf1md, int saltlen) | |||
517 | return NULL; | 629 | return NULL; |
518 | } | 630 | } |
519 | 631 | ||
632 | static ASN1_STRING * | ||
633 | rsa_ctx_to_pss_string(EVP_PKEY_CTX *pkctx) | ||
634 | { | ||
635 | RSA_PSS_PARAMS *pss = rsa_ctx_to_pss(pkctx); | ||
636 | ASN1_STRING *os; | ||
637 | |||
638 | if (pss == NULL) | ||
639 | return NULL; | ||
640 | |||
641 | os = ASN1_item_pack(pss, &RSA_PSS_PARAMS_it, NULL); | ||
642 | RSA_PSS_PARAMS_free(pss); | ||
643 | return os; | ||
644 | } | ||
645 | |||
646 | /* | ||
647 | * From PSS AlgorithmIdentifier set public key parameters. If pkey isn't NULL | ||
648 | * then the EVP_MD_CTX is setup and initialised. If it is NULL parameters are | ||
649 | * passed to pkctx instead. | ||
650 | */ | ||
651 | |||
652 | static int | ||
653 | rsa_pss_to_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pkctx, | ||
654 | X509_ALGOR *sigalg, EVP_PKEY *pkey) | ||
655 | { | ||
656 | int rv = -1; | ||
657 | int saltlen; | ||
658 | const EVP_MD *mgf1md = NULL, *md = NULL; | ||
659 | RSA_PSS_PARAMS *pss; | ||
660 | |||
661 | /* Sanity check: make sure it is PSS */ | ||
662 | if (OBJ_obj2nid(sigalg->algorithm) != EVP_PKEY_RSA_PSS) { | ||
663 | RSAerror(RSA_R_UNSUPPORTED_SIGNATURE_TYPE); | ||
664 | return -1; | ||
665 | } | ||
666 | /* Decode PSS parameters */ | ||
667 | pss = rsa_pss_decode(sigalg); | ||
668 | |||
669 | if (!rsa_pss_get_param(pss, &md, &mgf1md, &saltlen)) { | ||
670 | RSAerror(RSA_R_INVALID_PSS_PARAMETERS); | ||
671 | goto err; | ||
672 | } | ||
673 | |||
674 | /* We have all parameters now set up context */ | ||
675 | if (pkey) { | ||
676 | if (!EVP_DigestVerifyInit(ctx, &pkctx, md, NULL, pkey)) | ||
677 | goto err; | ||
678 | } else { | ||
679 | const EVP_MD *checkmd; | ||
680 | if (EVP_PKEY_CTX_get_signature_md(pkctx, &checkmd) <= 0) | ||
681 | goto err; | ||
682 | if (EVP_MD_type(md) != EVP_MD_type(checkmd)) { | ||
683 | RSAerror(RSA_R_DIGEST_DOES_NOT_MATCH); | ||
684 | goto err; | ||
685 | } | ||
686 | } | ||
687 | |||
688 | if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) <= 0) | ||
689 | goto err; | ||
690 | |||
691 | if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) <= 0) | ||
692 | goto err; | ||
693 | |||
694 | if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0) | ||
695 | goto err; | ||
696 | /* Carry on */ | ||
697 | rv = 1; | ||
698 | |||
699 | err: | ||
700 | RSA_PSS_PARAMS_free(pss); | ||
701 | return rv; | ||
702 | } | ||
703 | |||
520 | int | 704 | int |
521 | rsa_pss_get_param(const RSA_PSS_PARAMS *pss, const EVP_MD **pmd, | 705 | rsa_pss_get_param(const RSA_PSS_PARAMS *pss, const EVP_MD **pmd, |
522 | const EVP_MD **pmgf1md, int *psaltlen) | 706 | const EVP_MD **pmgf1md, int *psaltlen) |
@@ -551,187 +735,56 @@ rsa_pss_get_param(const RSA_PSS_PARAMS *pss, const EVP_MD **pmd, | |||
551 | return 1; | 735 | return 1; |
552 | } | 736 | } |
553 | 737 | ||
554 | /* Customised RSA item verification routine. This is called | 738 | /* |
555 | * when a signature is encountered requiring special handling. We | 739 | * Customised RSA item verification routine. This is called when a signature |
556 | * currently only handle PSS. | 740 | * is encountered requiring special handling. We currently only handle PSS. |
557 | */ | 741 | */ |
742 | |||
558 | static int | 743 | static int |
559 | rsa_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, | 744 | rsa_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, |
560 | X509_ALGOR *sigalg, ASN1_BIT_STRING *sig, EVP_PKEY *pkey) | 745 | X509_ALGOR *sigalg, ASN1_BIT_STRING *sig, EVP_PKEY *pkey) |
561 | { | 746 | { |
562 | int rv = -1; | ||
563 | int saltlen; | ||
564 | const EVP_MD *mgf1md = NULL, *md = NULL; | ||
565 | RSA_PSS_PARAMS *pss; | ||
566 | X509_ALGOR *maskHash; | ||
567 | EVP_PKEY_CTX *pkctx; | ||
568 | |||
569 | /* Sanity check: make sure it is PSS */ | 747 | /* Sanity check: make sure it is PSS */ |
570 | if (OBJ_obj2nid(sigalg->algorithm) != NID_rsassaPss) { | 748 | if (OBJ_obj2nid(sigalg->algorithm) != EVP_PKEY_RSA_PSS) { |
571 | RSAerror(RSA_R_UNSUPPORTED_SIGNATURE_TYPE); | 749 | RSAerror(RSA_R_UNSUPPORTED_SIGNATURE_TYPE); |
572 | return -1; | 750 | return -1; |
573 | } | 751 | } |
574 | 752 | if (rsa_pss_to_ctx(ctx, NULL, sigalg, pkey) > 0) { | |
575 | /* Decode PSS parameters */ | 753 | /* Carry on */ |
576 | pss = rsa_pss_decode(sigalg, &maskHash); | 754 | return 2; |
577 | |||
578 | if (pss == NULL) { | ||
579 | RSAerror(RSA_R_INVALID_PSS_PARAMETERS); | ||
580 | goto err; | ||
581 | } | ||
582 | /* Check mask and lookup mask hash algorithm */ | ||
583 | if (pss->maskGenAlgorithm) { | ||
584 | if (OBJ_obj2nid(pss->maskGenAlgorithm->algorithm) != NID_mgf1) { | ||
585 | RSAerror(RSA_R_UNSUPPORTED_MASK_ALGORITHM); | ||
586 | goto err; | ||
587 | } | ||
588 | if (!maskHash) { | ||
589 | RSAerror(RSA_R_UNSUPPORTED_MASK_PARAMETER); | ||
590 | goto err; | ||
591 | } | ||
592 | mgf1md = EVP_get_digestbyobj(maskHash->algorithm); | ||
593 | if (mgf1md == NULL) { | ||
594 | RSAerror(RSA_R_UNKNOWN_MASK_DIGEST); | ||
595 | goto err; | ||
596 | } | ||
597 | } else | ||
598 | mgf1md = EVP_sha1(); | ||
599 | |||
600 | if (pss->hashAlgorithm) { | ||
601 | md = EVP_get_digestbyobj(pss->hashAlgorithm->algorithm); | ||
602 | if (md == NULL) { | ||
603 | RSAerror(RSA_R_UNKNOWN_PSS_DIGEST); | ||
604 | goto err; | ||
605 | } | ||
606 | } else | ||
607 | md = EVP_sha1(); | ||
608 | |||
609 | if (pss->saltLength) { | ||
610 | saltlen = ASN1_INTEGER_get(pss->saltLength); | ||
611 | |||
612 | /* Could perform more salt length sanity checks but the main | ||
613 | * RSA routines will trap other invalid values anyway. | ||
614 | */ | ||
615 | if (saltlen < 0) { | ||
616 | RSAerror(RSA_R_INVALID_SALT_LENGTH); | ||
617 | goto err; | ||
618 | } | ||
619 | } else | ||
620 | saltlen = 20; | ||
621 | |||
622 | /* low-level routines support only trailer field 0xbc (value 1) | ||
623 | * and PKCS#1 says we should reject any other value anyway. | ||
624 | */ | ||
625 | if (pss->trailerField && ASN1_INTEGER_get(pss->trailerField) != 1) { | ||
626 | RSAerror(RSA_R_INVALID_TRAILER); | ||
627 | goto err; | ||
628 | } | 755 | } |
629 | 756 | return -1; | |
630 | /* We have all parameters now set up context */ | ||
631 | |||
632 | if (!EVP_DigestVerifyInit(ctx, &pkctx, md, NULL, pkey)) | ||
633 | goto err; | ||
634 | |||
635 | if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) <= 0) | ||
636 | goto err; | ||
637 | |||
638 | if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) <= 0) | ||
639 | goto err; | ||
640 | |||
641 | if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0) | ||
642 | goto err; | ||
643 | /* Carry on */ | ||
644 | rv = 2; | ||
645 | |||
646 | err: | ||
647 | RSA_PSS_PARAMS_free(pss); | ||
648 | if (maskHash) | ||
649 | X509_ALGOR_free(maskHash); | ||
650 | return rv; | ||
651 | } | 757 | } |
652 | 758 | ||
653 | static int | 759 | static int |
654 | rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, | 760 | rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, |
655 | X509_ALGOR *alg1, X509_ALGOR *alg2, ASN1_BIT_STRING *sig) | 761 | X509_ALGOR *alg1, X509_ALGOR *alg2, ASN1_BIT_STRING *sig) |
656 | { | 762 | { |
657 | int pad_mode; | ||
658 | EVP_PKEY_CTX *pkctx = ctx->pctx; | 763 | EVP_PKEY_CTX *pkctx = ctx->pctx; |
764 | int pad_mode; | ||
659 | 765 | ||
660 | if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) | 766 | if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) |
661 | return 0; | 767 | return 0; |
662 | if (pad_mode == RSA_PKCS1_PADDING) | 768 | if (pad_mode == RSA_PKCS1_PADDING) |
663 | return 2; | 769 | return 2; |
664 | if (pad_mode == RSA_PKCS1_PSS_PADDING) { | 770 | if (pad_mode == RSA_PKCS1_PSS_PADDING) { |
665 | const EVP_MD *sigmd, *mgf1md; | 771 | ASN1_STRING *os1 = NULL; |
666 | RSA_PSS_PARAMS *pss = NULL; | 772 | os1 = rsa_ctx_to_pss_string(pkctx); |
667 | X509_ALGOR *mgf1alg = NULL; | 773 | if (!os1) |
668 | ASN1_STRING *os1 = NULL, *os2 = NULL; | 774 | return 0; |
669 | EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(pkctx); | 775 | /* Duplicate parameters if we have to */ |
670 | int saltlen, rv = 0; | ||
671 | |||
672 | sigmd = EVP_MD_CTX_md(ctx); | ||
673 | if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0) | ||
674 | goto err; | ||
675 | if (!EVP_PKEY_CTX_get_rsa_pss_saltlen(pkctx, &saltlen)) | ||
676 | goto err; | ||
677 | if (saltlen == -1) | ||
678 | saltlen = EVP_MD_size(sigmd); | ||
679 | else if (saltlen == -2) { | ||
680 | saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2; | ||
681 | if (((EVP_PKEY_bits(pk) - 1) & 0x7) == 0) | ||
682 | saltlen--; | ||
683 | } | ||
684 | pss = RSA_PSS_PARAMS_new(); | ||
685 | if (!pss) | ||
686 | goto err; | ||
687 | if (saltlen != 20) { | ||
688 | pss->saltLength = ASN1_INTEGER_new(); | ||
689 | if (!pss->saltLength) | ||
690 | goto err; | ||
691 | if (!ASN1_INTEGER_set(pss->saltLength, saltlen)) | ||
692 | goto err; | ||
693 | } | ||
694 | if (EVP_MD_type(sigmd) != NID_sha1) { | ||
695 | pss->hashAlgorithm = X509_ALGOR_new(); | ||
696 | if (!pss->hashAlgorithm) | ||
697 | goto err; | ||
698 | X509_ALGOR_set_md(pss->hashAlgorithm, sigmd); | ||
699 | } | ||
700 | if (EVP_MD_type(mgf1md) != NID_sha1) { | ||
701 | ASN1_STRING *stmp = NULL; | ||
702 | /* need to embed algorithm ID inside another */ | ||
703 | mgf1alg = X509_ALGOR_new(); | ||
704 | X509_ALGOR_set_md(mgf1alg, mgf1md); | ||
705 | if (!ASN1_item_pack(mgf1alg, &X509_ALGOR_it, | ||
706 | &stmp)) | ||
707 | goto err; | ||
708 | pss->maskGenAlgorithm = X509_ALGOR_new(); | ||
709 | if (!pss->maskGenAlgorithm) | ||
710 | goto err; | ||
711 | X509_ALGOR_set0(pss->maskGenAlgorithm, | ||
712 | OBJ_nid2obj(NID_mgf1), V_ASN1_SEQUENCE, stmp); | ||
713 | } | ||
714 | /* Finally create string with pss parameter encoding. */ | ||
715 | if (!ASN1_item_pack(pss, &RSA_PSS_PARAMS_it, &os1)) | ||
716 | goto err; | ||
717 | if (alg2) { | 776 | if (alg2) { |
718 | os2 = ASN1_STRING_dup(os1); | 777 | ASN1_STRING *os2 = ASN1_STRING_dup(os1); |
719 | if (!os2) | 778 | if (!os2) { |
720 | goto err; | 779 | ASN1_STRING_free(os1); |
721 | X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_rsassaPss), | 780 | return 0; |
781 | } | ||
782 | X509_ALGOR_set0(alg2, OBJ_nid2obj(EVP_PKEY_RSA_PSS), | ||
722 | V_ASN1_SEQUENCE, os2); | 783 | V_ASN1_SEQUENCE, os2); |
723 | } | 784 | } |
724 | X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_rsassaPss), | 785 | X509_ALGOR_set0(alg1, OBJ_nid2obj(EVP_PKEY_RSA_PSS), |
725 | V_ASN1_SEQUENCE, os1); | 786 | V_ASN1_SEQUENCE, os1); |
726 | os1 = os2 = NULL; | 787 | return 3; |
727 | rv = 3; | ||
728 | err: | ||
729 | if (mgf1alg) | ||
730 | X509_ALGOR_free(mgf1alg); | ||
731 | if (pss) | ||
732 | RSA_PSS_PARAMS_free(pss); | ||
733 | ASN1_STRING_free(os1); | ||
734 | return rv; | ||
735 | } | 788 | } |
736 | return 2; | 789 | return 2; |
737 | } | 790 | } |
@@ -773,3 +826,31 @@ const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[] = { | |||
773 | .pkey_flags = ASN1_PKEY_ALIAS | 826 | .pkey_flags = ASN1_PKEY_ALIAS |
774 | } | 827 | } |
775 | }; | 828 | }; |
829 | |||
830 | const EVP_PKEY_ASN1_METHOD rsa_pss_asn1_meth = { | ||
831 | .pkey_id = EVP_PKEY_RSA_PSS, | ||
832 | .pkey_base_id = EVP_PKEY_RSA_PSS, | ||
833 | .pkey_flags = ASN1_PKEY_SIGPARAM_NULL, | ||
834 | |||
835 | .pem_str = "RSA-PSS", | ||
836 | .info = "OpenSSL RSA-PSS method", | ||
837 | |||
838 | .pub_decode = rsa_pub_decode, | ||
839 | .pub_encode = rsa_pub_encode, | ||
840 | .pub_cmp = rsa_pub_cmp, | ||
841 | .pub_print = rsa_pub_print, | ||
842 | |||
843 | .priv_decode = rsa_priv_decode, | ||
844 | .priv_encode = rsa_priv_encode, | ||
845 | .priv_print = rsa_priv_print, | ||
846 | |||
847 | .pkey_size = int_rsa_size, | ||
848 | .pkey_bits = rsa_bits, | ||
849 | |||
850 | .sig_print = rsa_sig_print, | ||
851 | |||
852 | .pkey_free = int_rsa_free, | ||
853 | .pkey_ctrl = rsa_pkey_ctrl, | ||
854 | .item_verify = rsa_item_verify, | ||
855 | .item_sign = rsa_item_sign | ||
856 | }; | ||
diff --git a/src/lib/libcrypto/rsa/rsa_err.c b/src/lib/libcrypto/rsa/rsa_err.c index 91d74307f0..9924dac581 100644 --- a/src/lib/libcrypto/rsa/rsa_err.c +++ b/src/lib/libcrypto/rsa/rsa_err.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: rsa_err.c,v 1.18 2019/10/31 13:56:29 jsing Exp $ */ | 1 | /* $OpenBSD: rsa_err.c,v 1.19 2019/11/01 03:45:13 jsing Exp $ */ |
2 | /* ==================================================================== | 2 | /* ==================================================================== |
3 | * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. | 3 | * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. |
4 | * | 4 | * |
@@ -90,6 +90,7 @@ static ERR_STRING_DATA RSA_str_reasons[] = { | |||
90 | {ERR_REASON(RSA_R_DATA_TOO_LARGE_FOR_MODULUS), "data too large for modulus"}, | 90 | {ERR_REASON(RSA_R_DATA_TOO_LARGE_FOR_MODULUS), "data too large for modulus"}, |
91 | {ERR_REASON(RSA_R_DATA_TOO_SMALL) , "data too small"}, | 91 | {ERR_REASON(RSA_R_DATA_TOO_SMALL) , "data too small"}, |
92 | {ERR_REASON(RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE), "data too small for key size"}, | 92 | {ERR_REASON(RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE), "data too small for key size"}, |
93 | {ERR_REASON(RSA_R_DIGEST_DOES_NOT_MATCH) , "digest does not match"}, | ||
93 | {ERR_REASON(RSA_R_DIGEST_NOT_ALLOWED) , "digest not allowed"}, | 94 | {ERR_REASON(RSA_R_DIGEST_NOT_ALLOWED) , "digest not allowed"}, |
94 | {ERR_REASON(RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY), "digest too big for rsa key"}, | 95 | {ERR_REASON(RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY), "digest too big for rsa key"}, |
95 | {ERR_REASON(RSA_R_DMP1_NOT_CONGRUENT_TO_D), "dmp1 not congruent to d"}, | 96 | {ERR_REASON(RSA_R_DMP1_NOT_CONGRUENT_TO_D), "dmp1 not congruent to d"}, |
diff --git a/src/lib/libcrypto/rsa/rsa_locl.h b/src/lib/libcrypto/rsa/rsa_locl.h index d69946f95c..621c89dc76 100644 --- a/src/lib/libcrypto/rsa/rsa_locl.h +++ b/src/lib/libcrypto/rsa/rsa_locl.h | |||
@@ -1,9 +1,13 @@ | |||
1 | /* $OpenBSD: rsa_locl.h,v 1.8 2019/10/31 13:56:29 jsing Exp $ */ | 1 | /* $OpenBSD: rsa_locl.h,v 1.9 2019/11/01 03:45:13 jsing Exp $ */ |
2 | 2 | ||
3 | __BEGIN_HIDDEN_DECLS | 3 | __BEGIN_HIDDEN_DECLS |
4 | 4 | ||
5 | #define RSA_MIN_MODULUS_BITS 512 | 5 | #define RSA_MIN_MODULUS_BITS 512 |
6 | 6 | ||
7 | /* Macros to test if a pkey or ctx is for a PSS key */ | ||
8 | #define pkey_is_pss(pkey) (pkey->ameth->pkey_id == EVP_PKEY_RSA_PSS) | ||
9 | #define pkey_ctx_is_pss(ctx) (ctx->pmeth->pkey_id == EVP_PKEY_RSA_PSS) | ||
10 | |||
7 | RSA_PSS_PARAMS *rsa_pss_params_create(const EVP_MD *sigmd, const EVP_MD *mgf1md, | 11 | RSA_PSS_PARAMS *rsa_pss_params_create(const EVP_MD *sigmd, const EVP_MD *mgf1md, |
8 | int saltlen); | 12 | int saltlen); |
9 | int rsa_pss_get_param(const RSA_PSS_PARAMS *pss, const EVP_MD **pmd, | 13 | int rsa_pss_get_param(const RSA_PSS_PARAMS *pss, const EVP_MD **pmd, |