s3_clnt.c
来自「一个用于点对点传输加密的工具包源码」· C语言 代码 · 共 1,741 行 · 第 1/3 页
C
1,741 行
s->s3->tmp.cert_req=0; if (s->s3->tmp.message_type == SSL3_MT_SERVER_DONE) { s->s3->tmp.reuse_message=1; return(1); } if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_REQUEST) { ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE); SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_WRONG_MESSAGE_TYPE); goto err; } /* TLS does not like anon-DH with client cert */ if (s->version > SSL3_VERSION) { l=s->s3->tmp.new_cipher->algorithms; if (l & SSL_aNULL) { ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE); SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER); goto err; } } d=p=(unsigned char *)s->init_buf->data; if ((ca_sk=sk_X509_NAME_new(ca_dn_cmp)) == NULL) { SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,ERR_R_MALLOC_FAILURE); goto err; } /* get the certificate types */ ctype_num= *(p++); if (ctype_num > SSL3_CT_NUMBER) ctype_num=SSL3_CT_NUMBER; for (i=0; i<ctype_num; i++) s->s3->tmp.ctype[i]= p[i]; p+=ctype_num; /* get the CA RDNs */ n2s(p,llen);#if 0{FILE *out;out=fopen("/tmp/vsign.der","w");fwrite(p,1,llen,out);fclose(out);}#endif if ((llen+ctype_num+2+1) != n) { ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR); SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_LENGTH_MISMATCH); goto err; } for (nc=0; nc<llen; ) { n2s(p,l); if ((l+nc+2) > llen) { if ((s->options & SSL_OP_NETSCAPE_CA_DN_BUG)) goto cont; /* netscape bugs */ ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR); SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_CA_DN_TOO_LONG); goto err; } q=p; if ((xn=d2i_X509_NAME(NULL,&q,l)) == NULL) { /* If netscape tolerance is on, ignore errors */ if (s->options & SSL_OP_NETSCAPE_CA_DN_BUG) goto cont; else { ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR); SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,ERR_R_ASN1_LIB); goto err; } } if (q != (p+l)) { ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR); SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,SSL_R_CA_DN_LENGTH_MISMATCH); goto err; } if (!sk_X509_NAME_push(ca_sk,xn)) { SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,ERR_R_MALLOC_FAILURE); goto err; } p+=l; nc+=l+2; } if (0) {cont: ERR_clear_error(); } /* we should setup a certificate to return.... */ s->s3->tmp.cert_req=1; s->s3->tmp.ctype_num=ctype_num; if (s->s3->tmp.ca_names != NULL) sk_X509_NAME_pop_free(s->s3->tmp.ca_names,X509_NAME_free); s->s3->tmp.ca_names=ca_sk; ca_sk=NULL; ret=1;err: if (ca_sk != NULL) sk_X509_NAME_pop_free(ca_sk,X509_NAME_free); return(ret); }static int ca_dn_cmp(const X509_NAME * const *a, const X509_NAME * const *b) { return(X509_NAME_cmp(*a,*b)); }static int ssl3_get_server_done(SSL *s) { int ok,ret=0; long n; n=ssl3_get_message(s, SSL3_ST_CR_SRVR_DONE_A, SSL3_ST_CR_SRVR_DONE_B, SSL3_MT_SERVER_DONE, 30, /* should be very small, like 0 :-) */ &ok); if (!ok) return((int)n); if (n > 0) { /* should contain no data */ ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECODE_ERROR); SSLerr(SSL_F_SSL3_GET_SERVER_DONE,SSL_R_LENGTH_MISMATCH); } ret=1; return(ret); }static int ssl3_send_client_key_exchange(SSL *s) { unsigned char *p,*d; int n; unsigned long l;#ifndef NO_RSA unsigned char *q; EVP_PKEY *pkey=NULL;#endif if (s->state == SSL3_ST_CW_KEY_EXCH_A) { d=(unsigned char *)s->init_buf->data; p= &(d[4]); l=s->s3->tmp.new_cipher->algorithms;#ifndef NO_RSA if (l & SSL_kRSA) { RSA *rsa; unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH]; if (s->session->sess_cert->peer_rsa_tmp != NULL) rsa=s->session->sess_cert->peer_rsa_tmp; else { pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509); if ((pkey == NULL) || (pkey->type != EVP_PKEY_RSA) || (pkey->pkey.rsa == NULL)) { SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,SSL_R_INTERNAL_ERROR); goto err; } rsa=pkey->pkey.rsa; EVP_PKEY_free(pkey); } tmp_buf[0]=s->client_version>>8; tmp_buf[1]=s->client_version&0xff; if (RAND_bytes(&(tmp_buf[2]),SSL_MAX_MASTER_KEY_LENGTH-2) <= 0) goto err; s->session->master_key_length=SSL_MAX_MASTER_KEY_LENGTH; q=p; /* Fix buf for TLS and beyond */ if (s->version > SSL3_VERSION) p+=2; n=RSA_public_encrypt(SSL_MAX_MASTER_KEY_LENGTH, tmp_buf,p,rsa,RSA_PKCS1_PADDING);#ifdef PKCS1_CHECK if (s->options & SSL_OP_PKCS1_CHECK_1) p[1]++; if (s->options & SSL_OP_PKCS1_CHECK_2) tmp_buf[0]=0x70;#endif if (n <= 0) { SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,SSL_R_BAD_RSA_ENCRYPT); goto err; } /* Fix buf for TLS and beyond */ if (s->version > SSL3_VERSION) { s2n(n,q); n+=2; } s->session->master_key_length= s->method->ssl3_enc->generate_master_secret(s, s->session->master_key, tmp_buf,SSL_MAX_MASTER_KEY_LENGTH); memset(tmp_buf,0,SSL_MAX_MASTER_KEY_LENGTH); } else#endif#ifndef NO_DH if (l & (SSL_kEDH|SSL_kDHr|SSL_kDHd)) { DH *dh_srvr,*dh_clnt; if (s->session->sess_cert->peer_dh_tmp != NULL) dh_srvr=s->session->sess_cert->peer_dh_tmp; else { /* we get them from the cert */ ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE); SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,SSL_R_UNABLE_TO_FIND_DH_PARAMETERS); goto err; } /* generate a new random key */ if ((dh_clnt=DHparams_dup(dh_srvr)) == NULL) { SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB); goto err; } if (!DH_generate_key(dh_clnt)) { SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB); goto err; } /* use the 'p' output buffer for the DH key, but * make sure to clear it out afterwards */ n=DH_compute_key(p,dh_srvr->pub_key,dh_clnt); if (n <= 0) { SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_DH_LIB); goto err; } /* generate master key from the result */ s->session->master_key_length= s->method->ssl3_enc->generate_master_secret(s, s->session->master_key,p,n); /* clean up */ memset(p,0,n); /* send off the data */ n=BN_num_bytes(dh_clnt->pub_key); s2n(n,p); BN_bn2bin(dh_clnt->pub_key,p); n+=2; DH_free(dh_clnt); /* perhaps clean things up a bit EAY EAY EAY EAY*/ } else#endif { ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE); SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,SSL_R_INTERNAL_ERROR); goto err; } *(d++)=SSL3_MT_CLIENT_KEY_EXCHANGE; l2n3(n,d); s->state=SSL3_ST_CW_KEY_EXCH_B; /* number of bytes to write */ s->init_num=n+4; s->init_off=0; } /* SSL3_ST_CW_KEY_EXCH_B */ return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));err: return(-1); }static int ssl3_send_client_verify(SSL *s) { unsigned char *p,*d; unsigned char data[MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH]; EVP_PKEY *pkey;#ifndef NO_RSA unsigned u=0;#endif unsigned long n;#ifndef NO_DSA int j;#endif if (s->state == SSL3_ST_CW_CERT_VRFY_A) { d=(unsigned char *)s->init_buf->data; p= &(d[4]); pkey=s->cert->key->privatekey; s->method->ssl3_enc->cert_verify_mac(s,&(s->s3->finish_dgst2), &(data[MD5_DIGEST_LENGTH]));#ifndef NO_RSA if (pkey->type == EVP_PKEY_RSA) { s->method->ssl3_enc->cert_verify_mac(s, &(s->s3->finish_dgst1),&(data[0])); if (RSA_sign(NID_md5_sha1, data, MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH, &(p[2]), &u, pkey->pkey.rsa) <= 0 ) { SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,ERR_R_RSA_LIB); goto err; } s2n(u,p); n=u+2; } else#endif#ifndef NO_DSA if (pkey->type == EVP_PKEY_DSA) { if (!DSA_sign(pkey->save_type, &(data[MD5_DIGEST_LENGTH]), SHA_DIGEST_LENGTH,&(p[2]), (unsigned int *)&j,pkey->pkey.dsa)) { SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,ERR_R_DSA_LIB); goto err; } s2n(j,p); n=j+2; } else#endif { SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY,SSL_R_INTERNAL_ERROR); goto err; } *(d++)=SSL3_MT_CERTIFICATE_VERIFY; l2n3(n,d); s->init_num=(int)n+4; s->init_off=0; } return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));err: return(-1); }static int ssl3_send_client_certificate(SSL *s) { X509 *x509=NULL; EVP_PKEY *pkey=NULL; int i; unsigned long l; if (s->state == SSL3_ST_CW_CERT_A) { if ((s->cert == NULL) || (s->cert->key->x509 == NULL) || (s->cert->key->privatekey == NULL)) s->state=SSL3_ST_CW_CERT_B; else s->state=SSL3_ST_CW_CERT_C; } /* We need to get a client cert */ if (s->state == SSL3_ST_CW_CERT_B) { /* If we get an error, we need to * ssl->rwstate=SSL_X509_LOOKUP; return(-1); * We then get retied later */ i=0; if (s->ctx->client_cert_cb != NULL) i=s->ctx->client_cert_cb(s,&(x509),&(pkey)); if (i < 0) { s->rwstate=SSL_X509_LOOKUP; return(-1); } s->rwstate=SSL_NOTHING; if ((i == 1) && (pkey != NULL) && (x509 != NULL)) { s->state=SSL3_ST_CW_CERT_B; if ( !SSL_use_certificate(s,x509) || !SSL_use_PrivateKey(s,pkey)) i=0; } else if (i == 1) { i=0; SSLerr(SSL_F_SSL3_SEND_CLIENT_CERTIFICATE,SSL_R_BAD_DATA_RETURNED_BY_CALLBACK); } if (x509 != NULL) X509_free(x509); if (pkey != NULL) EVP_PKEY_free(pkey); if (i == 0) { if (s->version == SSL3_VERSION) { s->s3->tmp.cert_req=0; ssl3_send_alert(s,SSL3_AL_WARNING,SSL_AD_NO_CERTIFICATE); return(1); } else { s->s3->tmp.cert_req=2; } } /* Ok, we have a cert */ s->state=SSL3_ST_CW_CERT_C; } if (s->state == SSL3_ST_CW_CERT_C) { s->state=SSL3_ST_CW_CERT_D; l=ssl3_output_cert_chain(s, (s->s3->tmp.cert_req == 2)?NULL:s->cert->key->x509); s->init_num=(int)l; s->init_off=0; } /* SSL3_ST_CW_CERT_D */ return(ssl3_do_write(s,SSL3_RT_HANDSHAKE)); }#define has_bits(i,m) (((i)&(m)) == (m))static int ssl3_check_cert_and_algorithm(SSL *s) { int i,idx; long algs; EVP_PKEY *pkey=NULL; SESS_CERT *sc;#ifndef NO_RSA RSA *rsa;#endif#ifndef NO_DH DH *dh;#endif sc=s->session->sess_cert; if (sc == NULL) { SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_INTERNAL_ERROR); goto err; } algs=s->s3->tmp.new_cipher->algorithms; /* we don't have a certificate */ if (algs & (SSL_aDH|SSL_aNULL)) return(1);#ifndef NO_RSA rsa=s->session->sess_cert->peer_rsa_tmp;#endif#ifndef NO_DH dh=s->session->sess_cert->peer_dh_tmp;#endif /* This is the passed certificate */ idx=sc->peer_cert_type; pkey=X509_get_pubkey(sc->peer_pkeys[idx].x509); i=X509_certificate_type(sc->peer_pkeys[idx].x509,pkey); EVP_PKEY_free(pkey); /* Check that we have a certificate if we require one */ if ((algs & SSL_aRSA) && !has_bits(i,EVP_PK_RSA|EVP_PKT_SIGN)) { SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_RSA_SIGNING_CERT); goto f_err; }#ifndef NO_DSA else if ((algs & SSL_aDSS) && !has_bits(i,EVP_PK_DSA|EVP_PKT_SIGN)) { SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DSA_SIGNING_CERT); goto f_err; }#endif#ifndef NO_RSA if ((algs & SSL_kRSA) && !(has_bits(i,EVP_PK_RSA|EVP_PKT_ENC) || (rsa != NULL))) { SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_RSA_ENCRYPTING_CERT); goto f_err; }#endif#ifndef NO_DH if ((algs & SSL_kEDH) && !(has_bits(i,EVP_PK_DH|EVP_PKT_EXCH) || (dh != NULL))) { SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DH_KEY); goto f_err; } else if ((algs & SSL_kDHr) && !has_bits(i,EVP_PK_DH|EVP_PKS_RSA)) { SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DH_RSA_CERT); goto f_err; }#ifndef NO_DSA else if ((algs & SSL_kDHd) && !has_bits(i,EVP_PK_DH|EVP_PKS_DSA)) { SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_DH_DSA_CERT); goto f_err; }#endif#endif if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && !has_bits(i,EVP_PKT_EXP)) {#ifndef NO_RSA if (algs & SSL_kRSA) { if (rsa == NULL || RSA_size(rsa) > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) { SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_EXPORT_TMP_RSA_KEY); goto f_err; } } else#endif#ifndef NO_DH if (algs & (SSL_kEDH|SSL_kDHr|SSL_kDHd)) { if (dh == NULL || DH_size(dh) > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) { SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_EXPORT_TMP_DH_KEY); goto f_err; } } else#endif { SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE); goto f_err; } } return(1);f_err: ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);err: return(0); }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?