diff options
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/libcrypto/rsa/rsa_sign.c | 268 |
1 files changed, 148 insertions, 120 deletions
diff --git a/src/lib/libcrypto/rsa/rsa_sign.c b/src/lib/libcrypto/rsa/rsa_sign.c index 6e9e869f0a..2383259dda 100644 --- a/src/lib/libcrypto/rsa/rsa_sign.c +++ b/src/lib/libcrypto/rsa/rsa_sign.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: rsa_sign.c,v 1.29 2017/05/02 03:59:45 deraadt Exp $ */ | 1 | /* $OpenBSD: rsa_sign.c,v 1.30 2018/07/23 17:37:17 tb 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 | * |
@@ -70,168 +70,196 @@ | |||
70 | /* Size of an SSL signature: MD5+SHA1 */ | 70 | /* Size of an SSL signature: MD5+SHA1 */ |
71 | #define SSL_SIG_LENGTH 36 | 71 | #define SSL_SIG_LENGTH 36 |
72 | 72 | ||
73 | int | 73 | static int encode_pkcs1(unsigned char **, int *, int , const unsigned char *, |
74 | RSA_sign(int type, const unsigned char *m, unsigned int m_len, | 74 | unsigned int); |
75 | unsigned char *sigret, unsigned int *siglen, RSA *rsa) | 75 | |
76 | /* | ||
77 | * encode_pkcs1 encodes a DigestInfo prefix of hash `type' and digest `m', as | ||
78 | * described in EMSA-PKCS-v1_5-ENCODE, RFC 8017 section 9. step 2. This | ||
79 | * encodes the DigestInfo (T and tLen) but does not add the padding. | ||
80 | * | ||
81 | * On success, it returns one and sets `*out' to a newly allocated buffer | ||
82 | * containing the result and `*out_len' to its length. Freeing `*out' is | ||
83 | * the caller's responsibility. Failure is indicated by zero. | ||
84 | */ | ||
85 | static int | ||
86 | encode_pkcs1(unsigned char **out, int *out_len, int type, | ||
87 | const unsigned char *m, unsigned int m_len) | ||
76 | { | 88 | { |
77 | X509_SIG sig; | 89 | X509_SIG sig; |
78 | ASN1_TYPE parameter; | ||
79 | int i, j, ret = 1; | ||
80 | unsigned char *p, *tmps = NULL; | ||
81 | const unsigned char *s = NULL; | ||
82 | X509_ALGOR algor; | 90 | X509_ALGOR algor; |
91 | ASN1_TYPE parameter; | ||
83 | ASN1_OCTET_STRING digest; | 92 | ASN1_OCTET_STRING digest; |
93 | uint8_t *der = NULL; | ||
94 | int len; | ||
95 | |||
96 | sig.algor = &algor; | ||
97 | if ((sig.algor->algorithm = OBJ_nid2obj(type)) == NULL) { | ||
98 | RSAerror(RSA_R_UNKNOWN_ALGORITHM_TYPE); | ||
99 | return 0; | ||
100 | } | ||
101 | if (sig.algor->algorithm->length == 0) { | ||
102 | RSAerror( | ||
103 | RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD); | ||
104 | return 0; | ||
105 | } | ||
106 | parameter.type = V_ASN1_NULL; | ||
107 | parameter.value.ptr = NULL; | ||
108 | sig.algor->parameter = ¶meter; | ||
109 | |||
110 | sig.digest = &digest; | ||
111 | sig.digest->data = (unsigned char*)m; /* TMP UGLY CAST */ | ||
112 | sig.digest->length = m_len; | ||
84 | 113 | ||
85 | if ((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_sign) | 114 | if ((len = i2d_X509_SIG(&sig, &der)) < 0) |
115 | return 0; | ||
116 | |||
117 | *out = der; | ||
118 | *out_len = len; | ||
119 | |||
120 | return 1; | ||
121 | } | ||
122 | |||
123 | int | ||
124 | RSA_sign(int type, const unsigned char *m, unsigned int m_len, | ||
125 | unsigned char *sigret, unsigned int *siglen, RSA *rsa) | ||
126 | { | ||
127 | const unsigned char *encoded = NULL; | ||
128 | unsigned char *tmps = NULL; | ||
129 | int encrypt_len, encoded_len = 0, ret = 0; | ||
130 | |||
131 | if ((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_sign != NULL) | ||
86 | return rsa->meth->rsa_sign(type, m, m_len, sigret, siglen, rsa); | 132 | return rsa->meth->rsa_sign(type, m, m_len, sigret, siglen, rsa); |
87 | 133 | ||
88 | /* Special case: SSL signature, just check the length */ | 134 | /* Compute the encoded digest. */ |
89 | if (type == NID_md5_sha1) { | 135 | if (type == NID_md5_sha1) { |
136 | /* | ||
137 | * NID_md5_sha1 corresponds to the MD5/SHA1 combination in | ||
138 | * TLS 1.1 and earlier. It has no DigestInfo wrapper but | ||
139 | * otherwise is RSASSA-PKCS-v1.5. | ||
140 | */ | ||
90 | if (m_len != SSL_SIG_LENGTH) { | 141 | if (m_len != SSL_SIG_LENGTH) { |
91 | RSAerror(RSA_R_INVALID_MESSAGE_LENGTH); | 142 | RSAerror(RSA_R_INVALID_DIGEST_LENGTH); |
92 | return 0; | 143 | return 0; |
93 | } | 144 | } |
94 | i = SSL_SIG_LENGTH; | 145 | encoded_len = SSL_SIG_LENGTH; |
95 | s = m; | 146 | encoded = m; |
96 | } else { | 147 | } else { |
97 | sig.algor = &algor; | 148 | if (!encode_pkcs1(&tmps, &encoded_len, type, m, m_len)) |
98 | sig.algor->algorithm = OBJ_nid2obj(type); | 149 | goto err; |
99 | if (sig.algor->algorithm == NULL) { | 150 | encoded = tmps; |
100 | RSAerror(RSA_R_UNKNOWN_ALGORITHM_TYPE); | ||
101 | return 0; | ||
102 | } | ||
103 | if (sig.algor->algorithm->length == 0) { | ||
104 | RSAerror(RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD); | ||
105 | return 0; | ||
106 | } | ||
107 | parameter.type = V_ASN1_NULL; | ||
108 | parameter.value.ptr = NULL; | ||
109 | sig.algor->parameter = ¶meter; | ||
110 | |||
111 | sig.digest = &digest; | ||
112 | sig.digest->data = (unsigned char *)m; /* TMP UGLY CAST */ | ||
113 | sig.digest->length = m_len; | ||
114 | |||
115 | i = i2d_X509_SIG(&sig, NULL); | ||
116 | } | 151 | } |
117 | j = RSA_size(rsa); | 152 | if (encoded_len > RSA_size(rsa) - RSA_PKCS1_PADDING_SIZE) { |
118 | if (i > j - RSA_PKCS1_PADDING_SIZE) { | ||
119 | RSAerror(RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); | 153 | RSAerror(RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); |
120 | return 0; | 154 | goto err; |
121 | } | ||
122 | if (type != NID_md5_sha1) { | ||
123 | tmps = malloc(j + 1); | ||
124 | if (tmps == NULL) { | ||
125 | RSAerror(ERR_R_MALLOC_FAILURE); | ||
126 | return 0; | ||
127 | } | ||
128 | p = tmps; | ||
129 | i2d_X509_SIG(&sig, &p); | ||
130 | s = tmps; | ||
131 | } | 155 | } |
132 | i = RSA_private_encrypt(i, s, sigret, rsa, RSA_PKCS1_PADDING); | 156 | if ((encrypt_len = RSA_private_encrypt(encoded_len, encoded, sigret, |
133 | if (i <= 0) | 157 | rsa, RSA_PKCS1_PADDING)) <= 0) |
134 | ret = 0; | 158 | goto err; |
135 | else | 159 | |
136 | *siglen = i; | 160 | *siglen = encrypt_len; |
137 | 161 | ret = 1; | |
138 | if (type != NID_md5_sha1) | 162 | |
139 | freezero(tmps, (unsigned int)j + 1); | 163 | err: |
164 | freezero(tmps, (size_t)encoded_len); | ||
140 | return (ret); | 165 | return (ret); |
141 | } | 166 | } |
142 | 167 | ||
168 | /* | ||
169 | * int_rsa_verify verifies an RSA signature in `sigbuf' using `rsa'. It may be | ||
170 | * called in two modes. If `rm' is NULL, it verifies the signature for the | ||
171 | * digest `m'. Otherwise, it recovers the digest from the signature, writing the | ||
172 | * digest to `rm' and the length to `*prm_len'. `type' is the NID of the digest | ||
173 | * algorithm to use. It returns one on successful verification and zero | ||
174 | * otherwise. | ||
175 | */ | ||
143 | int | 176 | int |
144 | int_rsa_verify(int dtype, const unsigned char *m, unsigned int m_len, | 177 | int_rsa_verify(int type, const unsigned char *m, unsigned int m_len, |
145 | unsigned char *rm, size_t *prm_len, const unsigned char *sigbuf, | 178 | unsigned char *rm, size_t *prm_len, const unsigned char *sigbuf, |
146 | size_t siglen, RSA *rsa) | 179 | size_t siglen, RSA *rsa) |
147 | { | 180 | { |
148 | int i, ret = 0, sigtype; | 181 | unsigned char *decrypt_buf, *encoded = NULL; |
149 | unsigned char *s; | 182 | int decrypt_len, encoded_len = 0, ret = 0; |
150 | X509_SIG *sig = NULL; | ||
151 | 183 | ||
152 | if (siglen != (unsigned int)RSA_size(rsa)) { | 184 | if (siglen != (size_t)RSA_size(rsa)) { |
153 | RSAerror(RSA_R_WRONG_SIGNATURE_LENGTH); | 185 | RSAerror(RSA_R_WRONG_SIGNATURE_LENGTH); |
154 | return 0; | 186 | return 0; |
155 | } | 187 | } |
156 | 188 | ||
157 | if ((dtype == NID_md5_sha1) && rm) { | 189 | /* Recover the encoded digest. */ |
158 | i = RSA_public_decrypt((int)siglen, sigbuf, rm, rsa, | 190 | if ((decrypt_buf = malloc(siglen)) == NULL) { |
159 | RSA_PKCS1_PADDING); | ||
160 | if (i <= 0) | ||
161 | return 0; | ||
162 | *prm_len = i; | ||
163 | return 1; | ||
164 | } | ||
165 | |||
166 | s = malloc(siglen); | ||
167 | if (s == NULL) { | ||
168 | RSAerror(ERR_R_MALLOC_FAILURE); | 191 | RSAerror(ERR_R_MALLOC_FAILURE); |
169 | goto err; | 192 | goto err; |
170 | } | 193 | } |
171 | if (dtype == NID_md5_sha1 && m_len != SSL_SIG_LENGTH) { | 194 | if ((decrypt_len = RSA_public_decrypt((int)siglen, sigbuf, decrypt_buf, |
172 | RSAerror(RSA_R_INVALID_MESSAGE_LENGTH); | 195 | rsa, RSA_PKCS1_PADDING)) <= 0) |
173 | goto err; | ||
174 | } | ||
175 | i = RSA_public_decrypt((int)siglen, sigbuf, s, rsa, RSA_PKCS1_PADDING); | ||
176 | |||
177 | if (i <= 0) | ||
178 | goto err; | 196 | goto err; |
197 | |||
198 | if (type == NID_md5_sha1) { | ||
199 | /* | ||
200 | * NID_md5_sha1 corresponds to the MD5/SHA1 combination in | ||
201 | * TLS 1.1 and earlier. It has no DigestInfo wrapper but | ||
202 | * otherwise is RSASSA-PKCS1-v1_5. | ||
203 | */ | ||
204 | if (decrypt_len != SSL_SIG_LENGTH) { | ||
205 | RSAerror(RSA_R_INVALID_DIGEST_LENGTH); | ||
206 | goto err; | ||
207 | } | ||
179 | 208 | ||
180 | /* Special case: SSL signature */ | 209 | if (rm != NULL) { |
181 | if (dtype == NID_md5_sha1) { | 210 | memcpy(rm, decrypt_buf, SSL_SIG_LENGTH); |
182 | if (i != SSL_SIG_LENGTH || memcmp(s, m, SSL_SIG_LENGTH)) | 211 | *prm_len = SSL_SIG_LENGTH; |
183 | RSAerror(RSA_R_BAD_SIGNATURE); | 212 | } else { |
184 | else | 213 | if (m_len != SSL_SIG_LENGTH) { |
185 | ret = 1; | 214 | RSAerror(RSA_R_INVALID_MESSAGE_LENGTH); |
215 | goto err; | ||
216 | } | ||
217 | if (memcmp(decrypt_buf, m, SSL_SIG_LENGTH) != 0) { | ||
218 | RSAerror(RSA_R_BAD_SIGNATURE); | ||
219 | goto err; | ||
220 | } | ||
221 | } | ||
186 | } else { | 222 | } else { |
187 | const unsigned char *p = s; | 223 | /* |
224 | * If recovering the digest, extract a digest-sized output from | ||
225 | * the end of `decrypt_buf' for `encode_pkcs1', then compare the | ||
226 | * decryption output as in a standard verification. | ||
227 | */ | ||
228 | if (rm != NULL) { | ||
229 | const EVP_MD *md; | ||
188 | 230 | ||
189 | sig = d2i_X509_SIG(NULL, &p, (long)i); | 231 | if ((md = EVP_get_digestbynid(type)) == NULL) { |
232 | RSAerror(RSA_R_UNKNOWN_ALGORITHM_TYPE); | ||
233 | goto err; | ||
234 | } | ||
235 | if ((m_len = EVP_MD_size(md)) > (size_t)decrypt_len) { | ||
236 | RSAerror(RSA_R_INVALID_DIGEST_LENGTH); | ||
237 | goto err; | ||
238 | } | ||
239 | m = decrypt_buf + decrypt_len - m_len; | ||
240 | } | ||
190 | 241 | ||
191 | if (sig == NULL) | 242 | /* Construct the encoded digest and ensure it matches */ |
243 | if (!encode_pkcs1(&encoded, &encoded_len, type, m, m_len)) | ||
192 | goto err; | 244 | goto err; |
193 | 245 | ||
194 | /* Excess data can be used to create forgeries */ | 246 | if (encoded_len != decrypt_len || |
195 | if (p != s + i) { | 247 | memcmp(encoded, decrypt_buf, encoded_len) != 0) { |
196 | RSAerror(RSA_R_BAD_SIGNATURE); | 248 | RSAerror(RSA_R_BAD_SIGNATURE); |
197 | goto err; | 249 | goto err; |
198 | } | 250 | } |
199 | 251 | ||
200 | /* Parameters to the signature algorithm can also be used to | 252 | /* Output the recovered digest. */ |
201 | create forgeries */ | 253 | if (rm != NULL) { |
202 | if (sig->algor->parameter && | 254 | memcpy(rm, m, m_len); |
203 | ASN1_TYPE_get(sig->algor->parameter) != V_ASN1_NULL) { | 255 | *prm_len = m_len; |
204 | RSAerror(RSA_R_BAD_SIGNATURE); | ||
205 | goto err; | ||
206 | } | 256 | } |
207 | |||
208 | sigtype = OBJ_obj2nid(sig->algor->algorithm); | ||
209 | |||
210 | if (sigtype != dtype) { | ||
211 | RSAerror(RSA_R_ALGORITHM_MISMATCH); | ||
212 | goto err; | ||
213 | } | ||
214 | if (rm) { | ||
215 | const EVP_MD *md; | ||
216 | |||
217 | md = EVP_get_digestbynid(dtype); | ||
218 | if (md && (EVP_MD_size(md) != sig->digest->length)) | ||
219 | RSAerror(RSA_R_INVALID_DIGEST_LENGTH); | ||
220 | else { | ||
221 | memcpy(rm, sig->digest->data, | ||
222 | sig->digest->length); | ||
223 | *prm_len = sig->digest->length; | ||
224 | ret = 1; | ||
225 | } | ||
226 | } else if ((unsigned int)sig->digest->length != m_len || | ||
227 | memcmp(m, sig->digest->data, m_len) != 0) { | ||
228 | RSAerror(RSA_R_BAD_SIGNATURE); | ||
229 | } else | ||
230 | ret = 1; | ||
231 | } | 257 | } |
232 | err: | 258 | |
233 | X509_SIG_free(sig); | 259 | ret = 1; |
234 | freezero(s, (unsigned int)siglen); | 260 | err: |
261 | freezero(encoded, (size_t)encoded_len); | ||
262 | freezero(decrypt_buf, siglen); | ||
235 | return ret; | 263 | return ret; |
236 | } | 264 | } |
237 | 265 | ||