diff options
author | jsing <> | 2018-08-27 17:04:34 +0000 |
---|---|---|
committer | jsing <> | 2018-08-27 17:04:34 +0000 |
commit | 611d369d0d6fc3d56632953485338f3a14d1780c (patch) | |
tree | 052672cb40ee76da40d52642aae057d9a0188587 /src | |
parent | a2babc9f69794977d3ff0af16beb774aa0c21e56 (diff) | |
download | openbsd-611d369d0d6fc3d56632953485338f3a14d1780c.tar.gz openbsd-611d369d0d6fc3d56632953485338f3a14d1780c.tar.bz2 openbsd-611d369d0d6fc3d56632953485338f3a14d1780c.zip |
Convert ssl3_get_cert_verify() to CBS and clean up somewhat.
ok inoguchi@
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libssl/ssl_srvr.c | 146 |
1 files changed, 72 insertions, 74 deletions
diff --git a/src/lib/libssl/ssl_srvr.c b/src/lib/libssl/ssl_srvr.c index b2314d5bbe..e046438cc0 100644 --- a/src/lib/libssl/ssl_srvr.c +++ b/src/lib/libssl/ssl_srvr.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl_srvr.c,v 1.47 2018/08/27 16:48:12 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_srvr.c,v 1.48 2018/08/27 17:04:34 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 | * |
@@ -2103,14 +2103,19 @@ ssl3_get_client_key_exchange(SSL *s) | |||
2103 | int | 2103 | int |
2104 | ssl3_get_cert_verify(SSL *s) | 2104 | ssl3_get_cert_verify(SSL *s) |
2105 | { | 2105 | { |
2106 | EVP_PKEY *pkey = NULL; | 2106 | CBS cbs, signature; |
2107 | unsigned char *p; | ||
2108 | int al, ok, ret = 0; | ||
2109 | long n; | ||
2110 | int type = 0, i, j; | ||
2111 | X509 *peer; | ||
2112 | const EVP_MD *md = NULL; | 2107 | const EVP_MD *md = NULL; |
2108 | EVP_PKEY *pkey = NULL; | ||
2109 | X509 *peer = NULL; | ||
2113 | EVP_MD_CTX mctx; | 2110 | EVP_MD_CTX mctx; |
2111 | uint8_t hash_id, sig_id; | ||
2112 | int al, ok, sigalg, verify; | ||
2113 | int type = 0; | ||
2114 | int ret = 0; | ||
2115 | long hdatalen; | ||
2116 | void *hdata; | ||
2117 | long n; | ||
2118 | |||
2114 | EVP_MD_CTX_init(&mctx); | 2119 | EVP_MD_CTX_init(&mctx); |
2115 | 2120 | ||
2116 | n = s->method->internal->ssl_get_message(s, SSL3_ST_SR_CERT_VRFY_A, | 2121 | n = s->method->internal->ssl_get_message(s, SSL3_ST_SR_CERT_VRFY_A, |
@@ -2118,13 +2123,15 @@ ssl3_get_cert_verify(SSL *s) | |||
2118 | if (!ok) | 2123 | if (!ok) |
2119 | return ((int)n); | 2124 | return ((int)n); |
2120 | 2125 | ||
2126 | if (n < 0) | ||
2127 | goto err; | ||
2128 | |||
2129 | CBS_init(&cbs, s->internal->init_msg, n); | ||
2130 | |||
2121 | if (s->session->peer != NULL) { | 2131 | if (s->session->peer != NULL) { |
2122 | peer = s->session->peer; | 2132 | peer = s->session->peer; |
2123 | pkey = X509_get_pubkey(peer); | 2133 | pkey = X509_get_pubkey(peer); |
2124 | type = X509_certificate_type(peer, pkey); | 2134 | type = X509_certificate_type(peer, pkey); |
2125 | } else { | ||
2126 | peer = NULL; | ||
2127 | pkey = NULL; | ||
2128 | } | 2135 | } |
2129 | 2136 | ||
2130 | if (S3I(s)->tmp.message_type != SSL3_MT_CERTIFICATE_VERIFY) { | 2137 | if (S3I(s)->tmp.message_type != SSL3_MT_CERTIFICATE_VERIFY) { |
@@ -2156,60 +2163,57 @@ ssl3_get_cert_verify(SSL *s) | |||
2156 | goto f_err; | 2163 | goto f_err; |
2157 | } | 2164 | } |
2158 | 2165 | ||
2159 | /* we now have a signature that we need to verify */ | ||
2160 | p = (unsigned char *)s->internal->init_msg; | ||
2161 | /* | 2166 | /* |
2162 | * Check for broken implementations of GOST ciphersuites. | 2167 | * Check for broken implementations of GOST ciphersuites. |
2163 | * | 2168 | * |
2164 | * If key is GOST and n is exactly 64, it is a bare | 2169 | * If key is GOST and n is exactly 64, it is a bare |
2165 | * signature without length field. | 2170 | * signature without length field. |
2166 | */ | 2171 | */ |
2167 | if (n == 64 && (pkey->type == NID_id_GostR3410_94 || | 2172 | if ((pkey->type == NID_id_GostR3410_94 || |
2168 | pkey->type == NID_id_GostR3410_2001) ) { | 2173 | pkey->type == NID_id_GostR3410_2001) && CBS_len(&cbs) == 64) { |
2169 | i = 64; | 2174 | CBS_dup(&cbs, &signature); |
2175 | if (!CBS_skip(&cbs, CBS_len(&cbs))) | ||
2176 | goto err; | ||
2170 | } else { | 2177 | } else { |
2171 | if (SSL_USE_SIGALGS(s)) { | 2178 | if (SSL_USE_SIGALGS(s)) { |
2172 | int sigalg = tls12_get_sigid(pkey); | 2179 | if (!CBS_get_u8(&cbs, &hash_id)) |
2173 | /* Should never happen */ | ||
2174 | if (sigalg == -1) { | ||
2175 | SSLerror(s, ERR_R_INTERNAL_ERROR); | ||
2176 | al = SSL_AD_INTERNAL_ERROR; | ||
2177 | goto f_err; | ||
2178 | } | ||
2179 | if (2 > n) | ||
2180 | goto truncated; | 2180 | goto truncated; |
2181 | /* Check key type is consistent with signature */ | 2181 | if (!CBS_get_u8(&cbs, &sig_id)) |
2182 | if (sigalg != (int)p[1]) { | 2182 | goto truncated; |
2183 | SSLerror(s, SSL_R_WRONG_SIGNATURE_TYPE); | 2183 | |
2184 | if ((md = tls12_get_hash(hash_id)) == NULL) { | ||
2185 | SSLerror(s, SSL_R_UNKNOWN_DIGEST); | ||
2184 | al = SSL_AD_DECODE_ERROR; | 2186 | al = SSL_AD_DECODE_ERROR; |
2185 | goto f_err; | 2187 | goto f_err; |
2186 | } | 2188 | } |
2187 | md = tls12_get_hash(p[0]); | 2189 | |
2188 | if (md == NULL) { | 2190 | /* Check key type is consistent with signature. */ |
2189 | SSLerror(s, SSL_R_UNKNOWN_DIGEST); | 2191 | if ((sigalg = tls12_get_sigid(pkey)) == -1) { |
2192 | /* Should never happen */ | ||
2193 | SSLerror(s, ERR_R_INTERNAL_ERROR); | ||
2194 | goto err; | ||
2195 | } | ||
2196 | if (sigalg != sig_id) { | ||
2197 | SSLerror(s, SSL_R_WRONG_SIGNATURE_TYPE); | ||
2190 | al = SSL_AD_DECODE_ERROR; | 2198 | al = SSL_AD_DECODE_ERROR; |
2191 | goto f_err; | 2199 | goto f_err; |
2192 | } | 2200 | } |
2193 | p += 2; | ||
2194 | n -= 2; | ||
2195 | } | 2201 | } |
2196 | if (2 > n) | 2202 | if (!CBS_get_u16_length_prefixed(&cbs, &signature)) |
2197 | goto truncated; | 2203 | goto err; |
2198 | n2s(p, i); | ||
2199 | n -= 2; | ||
2200 | if (i > n) | ||
2201 | goto truncated; | ||
2202 | } | 2204 | } |
2203 | j = EVP_PKEY_size(pkey); | 2205 | if (CBS_len(&signature) > EVP_PKEY_size(pkey)) { |
2204 | if ((i > j) || (n > j) || (n <= 0)) { | ||
2205 | SSLerror(s, SSL_R_WRONG_SIGNATURE_SIZE); | 2206 | SSLerror(s, SSL_R_WRONG_SIGNATURE_SIZE); |
2206 | al = SSL_AD_DECODE_ERROR; | 2207 | al = SSL_AD_DECODE_ERROR; |
2207 | goto f_err; | 2208 | goto f_err; |
2208 | } | 2209 | } |
2210 | if (CBS_len(&cbs) != 0) { | ||
2211 | al = SSL_AD_DECODE_ERROR; | ||
2212 | SSLerror(s, SSL_R_EXTRA_DATA_IN_MESSAGE); | ||
2213 | goto f_err; | ||
2214 | } | ||
2209 | 2215 | ||
2210 | if (SSL_USE_SIGALGS(s)) { | 2216 | if (SSL_USE_SIGALGS(s)) { |
2211 | long hdatalen = 0; | ||
2212 | void *hdata; | ||
2213 | hdatalen = BIO_get_mem_data(S3I(s)->handshake_buffer, &hdata); | 2217 | hdatalen = BIO_get_mem_data(S3I(s)->handshake_buffer, &hdata); |
2214 | if (hdatalen <= 0) { | 2218 | if (hdatalen <= 0) { |
2215 | SSLerror(s, ERR_R_INTERNAL_ERROR); | 2219 | SSLerror(s, ERR_R_INTERNAL_ERROR); |
@@ -2222,34 +2226,32 @@ ssl3_get_cert_verify(SSL *s) | |||
2222 | al = SSL_AD_INTERNAL_ERROR; | 2226 | al = SSL_AD_INTERNAL_ERROR; |
2223 | goto f_err; | 2227 | goto f_err; |
2224 | } | 2228 | } |
2225 | 2229 | if (EVP_VerifyFinal(&mctx, CBS_data(&signature), | |
2226 | if (EVP_VerifyFinal(&mctx, p, i, pkey) <= 0) { | 2230 | CBS_len(&signature), pkey) <= 0) { |
2227 | al = SSL_AD_DECRYPT_ERROR; | 2231 | al = SSL_AD_DECRYPT_ERROR; |
2228 | SSLerror(s, SSL_R_BAD_SIGNATURE); | 2232 | SSLerror(s, SSL_R_BAD_SIGNATURE); |
2229 | goto f_err; | 2233 | goto f_err; |
2230 | } | 2234 | } |
2231 | } else | 2235 | } else if (pkey->type == EVP_PKEY_RSA) { |
2232 | if (pkey->type == EVP_PKEY_RSA) { | 2236 | verify = RSA_verify(NID_md5_sha1, S3I(s)->tmp.cert_verify_md, |
2233 | i = RSA_verify(NID_md5_sha1, S3I(s)->tmp.cert_verify_md, | 2237 | MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, CBS_data(&signature), |
2234 | MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, p, i, | 2238 | CBS_len(&signature), pkey->pkey.rsa); |
2235 | pkey->pkey.rsa); | 2239 | if (verify < 0) { |
2236 | if (i < 0) { | ||
2237 | al = SSL_AD_DECRYPT_ERROR; | 2240 | al = SSL_AD_DECRYPT_ERROR; |
2238 | SSLerror(s, SSL_R_BAD_RSA_DECRYPT); | 2241 | SSLerror(s, SSL_R_BAD_RSA_DECRYPT); |
2239 | goto f_err; | 2242 | goto f_err; |
2240 | } | 2243 | } |
2241 | if (i == 0) { | 2244 | if (verify == 0) { |
2242 | al = SSL_AD_DECRYPT_ERROR; | 2245 | al = SSL_AD_DECRYPT_ERROR; |
2243 | SSLerror(s, SSL_R_BAD_RSA_SIGNATURE); | 2246 | SSLerror(s, SSL_R_BAD_RSA_SIGNATURE); |
2244 | goto f_err; | 2247 | goto f_err; |
2245 | } | 2248 | } |
2246 | } else | 2249 | } else if (pkey->type == EVP_PKEY_EC) { |
2247 | if (pkey->type == EVP_PKEY_EC) { | 2250 | verify = ECDSA_verify(pkey->save_type, |
2248 | j = ECDSA_verify(pkey->save_type, | ||
2249 | &(S3I(s)->tmp.cert_verify_md[MD5_DIGEST_LENGTH]), | 2251 | &(S3I(s)->tmp.cert_verify_md[MD5_DIGEST_LENGTH]), |
2250 | SHA_DIGEST_LENGTH, p, i, pkey->pkey.ec); | 2252 | SHA_DIGEST_LENGTH, CBS_data(&signature), |
2251 | if (j <= 0) { | 2253 | CBS_len(&signature), pkey->pkey.ec); |
2252 | /* bad signature */ | 2254 | if (verify <= 0) { |
2253 | al = SSL_AD_DECRYPT_ERROR; | 2255 | al = SSL_AD_DECRYPT_ERROR; |
2254 | SSLerror(s, SSL_R_BAD_ECDSA_SIGNATURE); | 2256 | SSLerror(s, SSL_R_BAD_ECDSA_SIGNATURE); |
2255 | goto f_err; | 2257 | goto f_err; |
@@ -2258,12 +2260,10 @@ ssl3_get_cert_verify(SSL *s) | |||
2258 | #ifndef OPENSSL_NO_GOST | 2260 | #ifndef OPENSSL_NO_GOST |
2259 | if (pkey->type == NID_id_GostR3410_94 || | 2261 | if (pkey->type == NID_id_GostR3410_94 || |
2260 | pkey->type == NID_id_GostR3410_2001) { | 2262 | pkey->type == NID_id_GostR3410_2001) { |
2261 | long hdatalen = 0; | 2263 | unsigned char sigbuf[128]; |
2262 | void *hdata; | 2264 | unsigned int siglen = sizeof(sigbuf); |
2263 | unsigned char signature[128]; | ||
2264 | unsigned int siglen = sizeof(signature); | ||
2265 | int nid; | ||
2266 | EVP_PKEY_CTX *pctx; | 2265 | EVP_PKEY_CTX *pctx; |
2266 | int nid; | ||
2267 | 2267 | ||
2268 | hdatalen = BIO_get_mem_data(S3I(s)->handshake_buffer, &hdata); | 2268 | hdatalen = BIO_get_mem_data(S3I(s)->handshake_buffer, &hdata); |
2269 | if (hdatalen <= 0) { | 2269 | if (hdatalen <= 0) { |
@@ -2272,33 +2272,31 @@ ssl3_get_cert_verify(SSL *s) | |||
2272 | goto f_err; | 2272 | goto f_err; |
2273 | } | 2273 | } |
2274 | if (!EVP_PKEY_get_default_digest_nid(pkey, &nid) || | 2274 | if (!EVP_PKEY_get_default_digest_nid(pkey, &nid) || |
2275 | !(md = EVP_get_digestbynid(nid))) { | 2275 | !(md = EVP_get_digestbynid(nid))) { |
2276 | SSLerror(s, ERR_R_EVP_LIB); | 2276 | SSLerror(s, ERR_R_EVP_LIB); |
2277 | al = SSL_AD_INTERNAL_ERROR; | 2277 | al = SSL_AD_INTERNAL_ERROR; |
2278 | goto f_err; | 2278 | goto f_err; |
2279 | } | 2279 | } |
2280 | pctx = EVP_PKEY_CTX_new(pkey, NULL); | 2280 | if ((pctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL) { |
2281 | if (!pctx) { | ||
2282 | SSLerror(s, ERR_R_EVP_LIB); | 2281 | SSLerror(s, ERR_R_EVP_LIB); |
2283 | al = SSL_AD_INTERNAL_ERROR; | 2282 | al = SSL_AD_INTERNAL_ERROR; |
2284 | goto f_err; | 2283 | goto f_err; |
2285 | } | 2284 | } |
2286 | if (!EVP_DigestInit_ex(&mctx, md, NULL) || | 2285 | if (!EVP_DigestInit_ex(&mctx, md, NULL) || |
2287 | !EVP_DigestUpdate(&mctx, hdata, hdatalen) || | 2286 | !EVP_DigestUpdate(&mctx, hdata, hdatalen) || |
2288 | !EVP_DigestFinal(&mctx, signature, &siglen) || | 2287 | !EVP_DigestFinal(&mctx, sigbuf, &siglen) || |
2289 | (EVP_PKEY_verify_init(pctx) <= 0) || | 2288 | (EVP_PKEY_verify_init(pctx) <= 0) || |
2290 | (EVP_PKEY_CTX_set_signature_md(pctx, md) <= 0) || | 2289 | (EVP_PKEY_CTX_set_signature_md(pctx, md) <= 0) || |
2291 | (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_VERIFY, | 2290 | (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_VERIFY, |
2292 | EVP_PKEY_CTRL_GOST_SIG_FORMAT, | 2291 | EVP_PKEY_CTRL_GOST_SIG_FORMAT, |
2293 | GOST_SIG_FORMAT_RS_LE, | 2292 | GOST_SIG_FORMAT_RS_LE, NULL) <= 0)) { |
2294 | NULL) <= 0)) { | ||
2295 | SSLerror(s, ERR_R_EVP_LIB); | 2293 | SSLerror(s, ERR_R_EVP_LIB); |
2296 | al = SSL_AD_INTERNAL_ERROR; | 2294 | al = SSL_AD_INTERNAL_ERROR; |
2297 | EVP_PKEY_CTX_free(pctx); | 2295 | EVP_PKEY_CTX_free(pctx); |
2298 | goto f_err; | 2296 | goto f_err; |
2299 | } | 2297 | } |
2300 | 2298 | if (EVP_PKEY_verify(pctx, CBS_data(&signature), | |
2301 | if (EVP_PKEY_verify(pctx, p, i, signature, siglen) <= 0) { | 2299 | CBS_len(&signature), sigbuf, siglen) <= 0) { |
2302 | al = SSL_AD_DECRYPT_ERROR; | 2300 | al = SSL_AD_DECRYPT_ERROR; |
2303 | SSLerror(s, SSL_R_BAD_SIGNATURE); | 2301 | SSLerror(s, SSL_R_BAD_SIGNATURE); |
2304 | EVP_PKEY_CTX_free(pctx); | 2302 | EVP_PKEY_CTX_free(pctx); |
@@ -2314,21 +2312,21 @@ ssl3_get_cert_verify(SSL *s) | |||
2314 | goto f_err; | 2312 | goto f_err; |
2315 | } | 2313 | } |
2316 | 2314 | ||
2317 | |||
2318 | ret = 1; | 2315 | ret = 1; |
2319 | if (0) { | 2316 | if (0) { |
2320 | truncated: | 2317 | truncated: |
2321 | al = SSL_AD_DECODE_ERROR; | 2318 | al = SSL_AD_DECODE_ERROR; |
2322 | SSLerror(s, SSL_R_BAD_PACKET_LENGTH); | 2319 | SSLerror(s, SSL_R_BAD_PACKET_LENGTH); |
2323 | f_err: | 2320 | f_err: |
2324 | ssl3_send_alert(s, SSL3_AL_FATAL, al); | 2321 | ssl3_send_alert(s, SSL3_AL_FATAL, al); |
2325 | } | 2322 | } |
2326 | end: | 2323 | end: |
2327 | if (S3I(s)->handshake_buffer) { | 2324 | if (S3I(s)->handshake_buffer) { |
2328 | BIO_free(S3I(s)->handshake_buffer); | 2325 | BIO_free(S3I(s)->handshake_buffer); |
2329 | S3I(s)->handshake_buffer = NULL; | 2326 | S3I(s)->handshake_buffer = NULL; |
2330 | s->s3->flags &= ~TLS1_FLAGS_KEEP_HANDSHAKE; | 2327 | s->s3->flags &= ~TLS1_FLAGS_KEEP_HANDSHAKE; |
2331 | } | 2328 | } |
2329 | err: | ||
2332 | EVP_MD_CTX_cleanup(&mctx); | 2330 | EVP_MD_CTX_cleanup(&mctx); |
2333 | EVP_PKEY_free(pkey); | 2331 | EVP_PKEY_free(pkey); |
2334 | return (ret); | 2332 | return (ret); |