📄 s3_srvr.c
字号:
goto err; } /* Let's get client's public key */ if ((clnt_ecpoint = EC_POINT_new(group)) == NULL) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); goto err; } if (n == 0L) { /* Client Publickey was in Client Certificate */ if (l & SSL_kECDHE) { al=SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_MISSING_TMP_ECDH_KEY); goto f_err; } if (((clnt_pub_pkey=X509_get_pubkey(s->session->peer)) == NULL) || (clnt_pub_pkey->type != EVP_PKEY_EC)) { /* XXX: For now, we do not support client * authentication using ECDH certificates * so this branch (n == 0L) of the code is * never executed. When that support is * added, we ought to ensure the key * received in the certificate is * authorized for key agreement. * ECDH_compute_key implicitly checks that * the two ECDH shares are for the same * group. */ al=SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_UNABLE_TO_DECODE_ECDH_CERTS); goto f_err; } EC_POINT_copy(clnt_ecpoint, EC_KEY_get0_public_key(clnt_pub_pkey->pkey.ec)); ret = 2; /* Skip certificate verify processing */ } else { /* Get client's public key from encoded point * in the ClientKeyExchange message. */ if ((bn_ctx = BN_CTX_new()) == NULL) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); goto err; } /* Get encoded point length */ i = *p; p += 1; if (EC_POINT_oct2point(group, clnt_ecpoint, p, i, bn_ctx) == 0) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB); goto err; } /* p is pointing to somewhere in the buffer * currently, so set it to the start */ p=(unsigned char *)s->init_buf->data; } /* Compute the shared pre-master secret */ field_size = EC_GROUP_get_degree(group); if (field_size <= 0) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); goto err; } /* If field size is not more than 24 octets, then use SHA-1 hash of result; * otherwise, use result (see section 4.8 of draft-ietf-tls-ecc-03.txt; * this is new with this version of the Internet Draft). */ if (field_size <= 24 * 8) i = ECDH_compute_key(p, KDF1_SHA1_len, clnt_ecpoint, srvr_ecdh, KDF1_SHA1); else i = ECDH_compute_key(p, (field_size+7)/8, clnt_ecpoint, srvr_ecdh, NULL); if (i <= 0) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); goto err; } EVP_PKEY_free(clnt_pub_pkey); EC_POINT_free(clnt_ecpoint); if (srvr_ecdh != NULL) EC_KEY_free(srvr_ecdh); BN_CTX_free(bn_ctx); /* Compute the master secret */ s->session->master_key_length = s->method->ssl3_enc-> \ generate_master_secret(s, s->session->master_key, p, i); OPENSSL_cleanse(p, i); return (ret); } else#endif { al=SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_UNKNOWN_CIPHER_TYPE); goto f_err; } return(1);f_err: ssl3_send_alert(s,SSL3_AL_FATAL,al);#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_ECDH)err:#endif#ifndef OPENSSL_NO_ECDH EVP_PKEY_free(clnt_pub_pkey); EC_POINT_free(clnt_ecpoint); if (srvr_ecdh != NULL) EC_KEY_free(srvr_ecdh); BN_CTX_free(bn_ctx);#endif return(-1); }int ssl3_get_cert_verify(SSL *s) { EVP_PKEY *pkey=NULL; unsigned char *p; int al,ok,ret=0; long n; int type=0,i,j; X509 *peer; n=s->method->ssl_get_message(s, SSL3_ST_SR_CERT_VRFY_A, SSL3_ST_SR_CERT_VRFY_B, -1, 514, /* 514? */ &ok); if (!ok) return((int)n); if (s->session->peer != NULL) { peer=s->session->peer; pkey=X509_get_pubkey(peer); type=X509_certificate_type(peer,pkey); } else { peer=NULL; pkey=NULL; } if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_VERIFY) { s->s3->tmp.reuse_message=1; if ((peer != NULL) && (type | EVP_PKT_SIGN)) { al=SSL_AD_UNEXPECTED_MESSAGE; SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_MISSING_VERIFY_MESSAGE); goto f_err; } ret=1; goto end; } if (peer == NULL) { SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_NO_CLIENT_CERT_RECEIVED); al=SSL_AD_UNEXPECTED_MESSAGE; goto f_err; } if (!(type & EVP_PKT_SIGN)) { SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE); al=SSL_AD_ILLEGAL_PARAMETER; goto f_err; } if (s->s3->change_cipher_spec) { SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_CCS_RECEIVED_EARLY); al=SSL_AD_UNEXPECTED_MESSAGE; goto f_err; } /* we now have a signature that we need to verify */ p=(unsigned char *)s->init_msg; n2s(p,i); n-=2; if (i > n) { SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_LENGTH_MISMATCH); al=SSL_AD_DECODE_ERROR; goto f_err; } j=EVP_PKEY_size(pkey); if ((i > j) || (n > j) || (n <= 0)) { SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_WRONG_SIGNATURE_SIZE); al=SSL_AD_DECODE_ERROR; goto f_err; }#ifndef OPENSSL_NO_RSA if (pkey->type == EVP_PKEY_RSA) { i=RSA_verify(NID_md5_sha1, s->s3->tmp.cert_verify_md, MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH, p, i, pkey->pkey.rsa); if (i < 0) { al=SSL_AD_DECRYPT_ERROR; SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_BAD_RSA_DECRYPT); goto f_err; } if (i == 0) { al=SSL_AD_DECRYPT_ERROR; SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_BAD_RSA_SIGNATURE); goto f_err; } } else#endif#ifndef OPENSSL_NO_DSA if (pkey->type == EVP_PKEY_DSA) { j=DSA_verify(pkey->save_type, &(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]), SHA_DIGEST_LENGTH,p,i,pkey->pkey.dsa); if (j <= 0) { /* bad signature */ al=SSL_AD_DECRYPT_ERROR; SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_BAD_DSA_SIGNATURE); goto f_err; } } else#endif#ifndef OPENSSL_NO_ECDSA if (pkey->type == EVP_PKEY_EC) { j=ECDSA_verify(pkey->save_type, &(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]), SHA_DIGEST_LENGTH,p,i,pkey->pkey.ec); if (j <= 0) { /* bad signature */ al=SSL_AD_DECRYPT_ERROR; SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_BAD_ECDSA_SIGNATURE); goto f_err; } } else#endif { SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,ERR_R_INTERNAL_ERROR); al=SSL_AD_UNSUPPORTED_CERTIFICATE; goto f_err; } ret=1; if (0) {f_err: ssl3_send_alert(s,SSL3_AL_FATAL,al); }end: EVP_PKEY_free(pkey); return(ret); }int ssl3_get_client_certificate(SSL *s) { int i,ok,al,ret= -1; X509 *x=NULL; unsigned long l,nc,llen,n; const unsigned char *p,*q; unsigned char *d; STACK_OF(X509) *sk=NULL; n=s->method->ssl_get_message(s, SSL3_ST_SR_CERT_A, SSL3_ST_SR_CERT_B, -1, s->max_cert_list, &ok); if (!ok) return((int)n); if (s->s3->tmp.message_type == SSL3_MT_CLIENT_KEY_EXCHANGE) { if ( (s->verify_mode & SSL_VERIFY_PEER) && (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) { SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); al=SSL_AD_HANDSHAKE_FAILURE; goto f_err; } /* If tls asked for a client cert, the client must return a 0 list */ if ((s->version > SSL3_VERSION) && s->s3->tmp.cert_request) { SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST); al=SSL_AD_UNEXPECTED_MESSAGE; goto f_err; } s->s3->tmp.reuse_message=1; return(1); } if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE) { al=SSL_AD_UNEXPECTED_MESSAGE; SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_WRONG_MESSAGE_TYPE); goto f_err; } p=d=(unsigned char *)s->init_msg; if ((sk=sk_X509_new_null()) == NULL) { SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,ERR_R_MALLOC_FAILURE); goto err; } n2l3(p,llen); if (llen+3 != n) { al=SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_LENGTH_MISMATCH); goto f_err; } for (nc=0; nc<llen; ) { n2l3(p,l); if ((l+nc+3) > llen) { al=SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_CERT_LENGTH_MISMATCH); goto f_err; } q=p; x=d2i_X509(NULL,&p,l); if (x == NULL) { SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,ERR_R_ASN1_LIB); goto err; } if (p != (q+l)) { al=SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_CERT_LENGTH_MISMATCH); goto f_err; } if (!sk_X509_push(sk,x)) { SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,ERR_R_MALLOC_FAILURE); goto err; } x=NULL; nc+=l+3; } if (sk_X509_num(sk) <= 0) { /* TLS does not mind 0 certs returned */ if (s->version == SSL3_VERSION) { al=SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_NO_CERTIFICATES_RETURNED); goto f_err; } /* Fail for TLS only if we required a certificate */ else if ((s->verify_mode & SSL_VERIFY_PEER) && (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) { SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); al=SSL_AD_HANDSHAKE_FAILURE; goto f_err; } } else { i=ssl_verify_cert_chain(s,sk); if (!i) { al=ssl_verify_alarm_type(s->verify_result); SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_NO_CERTIFICATE_RETURNED); goto f_err; } } if (s->session->peer != NULL) /* This should not be needed */ X509_free(s->session->peer); s->session->peer=sk_X509_shift(sk); s->session->verify_result = s->verify_result; /* With the current implementation, sess_cert will always be NULL * when we arrive here. */ if (s->session->sess_cert == NULL) { s->session->sess_cert = ssl_sess_cert_new(); if (s->session->sess_cert == NULL) { SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ERR_R_MALLOC_FAILURE); goto err; } } if (s->session->sess_cert->cert_chain != NULL) sk_X509_pop_free(s->session->sess_cert->cert_chain, X509_free); s->session->sess_cert->cert_chain=sk; /* Inconsistency alert: cert_chain does *not* include the * peer's own certificate, while we do include it in s3_clnt.c */ sk=NULL; ret=1; if (0) {f_err: ssl3_send_alert(s,SSL3_AL_FATAL,al); }err: if (x != NULL) X509_free(x); if (sk != NULL) sk_X509_pop_free(sk,X509_free); return(ret); }int ssl3_send_server_certificate(SSL *s) { unsigned long l; X509 *x; if (s->state == SSL3_ST_SW_CERT_A) { x=ssl_get_server_send_cert(s); if (x == NULL && /* VRS: allow null cert if auth == KRB5 */ (s->s3->tmp.new_cipher->algorithms & (SSL_MKEY_MASK|SSL_AUTH_MASK)) != (SSL_aKRB5|SSL_kKRB5)) { SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE,ERR_R_INTERNAL_ERROR); return(0); } l=ssl3_output_cert_chain(s,x); s->state=SSL3_ST_SW_CERT_B; s->init_num=(int)l; s->init_off=0; } /* SSL3_ST_SW_CERT_B */ return(ssl3_do_write(s,SSL3_RT_HANDSHAKE)); }#ifndef OPENSSL_NO_ECDH/* This is the complement of curve_id2nid in s3_clnt.c. */static int nid2curve_id(int nid){ /* ECC curves from draft-ietf-tls-ecc-01.txt (Mar 15, 2001) * (no changes in draft-ietf-tls-ecc-03.txt [June 2003]) */ switch (nid) { case NID_sect163k1: /* sect163k1 (1) */ return 1; case NID_sect163r1: /* sect163r1 (2) */ return 2; case NID_sect163r2: /* sect163r2 (3) */ return 3; case NID_sect193r1: /* sect193r1 (4) */ return 4; case NID_sect193r2: /* sect193r2 (5) */ return 5; case NID_sect233k1: /* sect233k1 (6) */ return 6; case NID_sect233r1: /* sect233r1 (7) */ return 7; case NID_sect239k1: /* sect239k1 (8) */ return 8; case NID_sect283k1: /* sect283k1 (9) */ return 9; case NID_sect283r1: /* sect283r1 (10) */ return 10; case NID_sect409k1: /* sect409k1 (11) */ return 11; case NID_sect409r1: /* sect409r1 (12) */ return 12; case NID_sect571k1: /* sect571k1 (13) */ return 13; case NID_sect571r1: /* sect571r1 (14) */ return 14; case NID_secp160k1: /* secp160k1 (15) */ return 15; case NID_secp160r1: /* secp160r1 (16) */ return 16; case NID_secp160r2: /* secp160r2 (17) */ return
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -