Certificate

一、构造请求 #

1. 构造服务端证书 #

2. 构造客户端证书 #

 1/* 到这一步的堆栈信息
 2libssl.so.3!tls_construct_client_certificate(SSL * s, WPACKET * pkt) (/ssl/statem/statem_clnt.c:3504)
 3libssl.so.3!write_state_machine(SSL * s) (/ssl/statem/statem.c:855)
 4libssl.so.3!state_machine(SSL * s, int server) (/ssl/statem/statem.c:451)
 5libssl.so.3!ossl_statem_connect(SSL * s) (/ssl/statem/statem.c:265)
 6libssl.so.3!ssl3_write_bytes(SSL * s, int type, const void * buf_, size_t len, size_t * written) (/ssl/record/rec_layer_s3.c:398)
 7libssl.so.3!ssl3_write(SSL * s, const void * buf, size_t len, size_t * written) (/ssl/s3_lib.c:4449)
 8libssl.so.3!ssl_write_internal(SSL * s, const void * buf, size_t num, size_t * written) (/ssl/ssl_lib.c:2062)
 9libssl.so.3!SSL_write(SSL * s, const void * buf, int num) (/ssl/ssl_lib.c:2140)
10s_client_main(int argc, char ** argv) (/apps/s_client.c:2841)
11do_cmd(struct lhash_st_FUNCTION * prog, int argc, char ** argv) (/apps/openssl.c:418)
12main(int argc, char ** argv) (/apps/openssl.c:298)
13 */
14// ssl/statem/statem_clnt.c
15int tls_construct_client_certificate(SSL *s, WPACKET *pkt)
16{
17    if (SSL_IS_TLS13(s)) {
18        if (s->pha_context == NULL) {
19            /* no context available, add 0-length context */
20            if (!WPACKET_put_bytes_u8(pkt, 0)) {
21                SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
22                return 0;
23            }
24        } else if (!WPACKET_sub_memcpy_u8(pkt, s->pha_context, s->pha_context_len)) {
25            SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
26            return 0;
27        }
28    }
29    if (!ssl3_output_cert_chain(s, pkt,
30                                (s->s3.tmp.cert_req == 2) ? NULL
31                                                           : s->cert->key)) {
32        /* SSLfatal() already called */
33        return 0;
34    }
35
36    if (SSL_IS_TLS13(s)
37            && SSL_IS_FIRST_HANDSHAKE(s)
38            && (!s->method->ssl3_enc->change_cipher_state(s,
39                    SSL3_CC_HANDSHAKE | SSL3_CHANGE_CIPHER_CLIENT_WRITE))) {
40        /*
41         * This is a fatal error, which leaves enc_write_ctx in an inconsistent
42         * state and thus ssl3_send_alert may crash.
43         */
44        SSLfatal(s, SSL_AD_NO_ALERT, SSL_R_CANNOT_CHANGE_CIPHER);
45        return 0;
46    }
47
48    return 1;
49}

二、处理请求 #

1. 客户端收到服务端的Certificate #

1.1. 证书完整性校验 #

  1/*
  2libcrypto.so.3!internal_verify(X509_STORE_CTX * ctx) (crypto/x509/x509_vfy.c:1823)
  3libcrypto.so.3!verify_chain(X509_STORE_CTX * ctx) (crypto/x509/x509_vfy.c:229)
  4libcrypto.so.3!X509_verify_cert(X509_STORE_CTX * ctx) (crypto/x509/x509_vfy.c:295)
  5libssl.so.3!ssl_verify_cert_chain(SSL * s, struct stack_st_X509 * sk) (ssl/ssl_cert.c:446)
  6libssl.so.3!tls_post_process_server_certificate(SSL * s, WORK_STATE wst) (ssl/statem/statem_clnt.c:1870)
  7libssl.so.3!ossl_statem_client_post_process_message(SSL * s, WORK_STATE wst) (ssl/statem/statem_clnt.c:1085)
  8libssl.so.3!read_state_machine(SSL * s) (ssl/statem/statem.c:675)
  9libssl.so.3!state_machine(SSL * s, int server) (ssl/statem/statem.c:442)
 10libssl.so.3!ossl_statem_connect(SSL * s) (ssl/statem/statem.c:265)
 11libssl.so.3!ssl3_write_bytes(SSL * s, int type, const void * buf_, size_t len, size_t * written) (ssl/record/rec_layer_s3.c:398)
 12libssl.so.3!ssl3_write(SSL * s, const void * buf, size_t len, size_t * written) (ssl/s3_lib.c:4449)
 13libssl.so.3!ssl_write_internal(SSL * s, const void * buf, size_t num, size_t * written) (ssl/ssl_lib.c:2062)
 14libssl.so.3!SSL_write(SSL * s, const void * buf, int num) (ssl/ssl_lib.c:2140)
 15s_client_main(int argc, char ** argv) (apps/s_client.c:2841)
 16do_cmd(struct lhash_st_FUNCTION * prog, int argc, char ** argv) (apps/openssl.c:418)
 17main(int argc, char ** argv) (apps/openssl.c:298)
 18 */
 19/*
 20 * Verify the issuer signatures and cert times of ctx->chain.
 21 * Sadly, returns 0 also on internal error.
 22 */
 23static int internal_verify(X509_STORE_CTX *ctx)
 24{
 25    int n = sk_X509_num(ctx->chain) - 1;
 26    X509 *xi = sk_X509_value(ctx->chain, n);
 27    X509 *xs = xi;
 28
 29    ctx->error_depth = n;
 30    if (ctx->bare_ta_signed) {
 31        /*
 32         * With DANE-verified bare public key TA signatures,
 33         * on the top certificate we check only the timestamps.
 34         * We report the issuer as NULL because all we have is a bare key.
 35         */
 36        xi = NULL;
 37    } else if (ossl_x509_likely_issued(xi, xi) != X509_V_OK
 38               /* exceptional case: last cert in the chain is not self-issued */
 39               && ((ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) == 0)) {
 40        if (n > 0) {
 41            n--;
 42            ctx->error_depth = n;
 43            xs = sk_X509_value(ctx->chain, n);
 44        } else {
 45            CB_FAIL_IF(1, ctx, xi, 0,
 46                       X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE);
 47        }
 48        /*
 49         * The below code will certainly not do a
 50         * self-signature check on xi because it is not self-issued.
 51         */
 52    }
 53
 54    /*
 55     * Do not clear error (by ctx->error = X509_V_OK), it must be "sticky",
 56     * only the user's callback is allowed to reset errors (at its own peril).
 57     */
 58    while (n >= 0) {
 59        /*-
 60         * For each iteration of this loop:
 61         * n is the subject depth
 62         * xs is the subject cert, for which the signature is to be checked
 63         * xi is NULL for DANE-verified bare public key TA signatures
 64         *       else the supposed issuer cert containing the public key to use
 65         * Initially xs == xi if the last cert in the chain is self-issued.
 66         */
 67        /*
 68         * Do signature check for self-signed certificates only if explicitly
 69         * asked for because it does not add any security and just wastes time.
 70         */
 71        if (xi != NULL
 72            && (xs != xi
 73                || ((ctx->param->flags & X509_V_FLAG_CHECK_SS_SIGNATURE) != 0
 74                    && (xi->ex_flags & EXFLAG_SS) != 0))) {
 75            EVP_PKEY *pkey;
 76            /*
 77             * If the issuer's public key is not available or its key usage
 78             * does not support issuing the subject cert, report the issuer
 79             * cert and its depth (rather than n, the depth of the subject).
 80             */
 81            int issuer_depth = n + (xs == xi ? 0 : 1);
 82            /*
 83             * According to https://tools.ietf.org/html/rfc5280#section-6.1.4
 84             * step (n) we must check any given key usage extension in a CA cert
 85             * when preparing the verification of a certificate issued by it.
 86             * According to https://tools.ietf.org/html/rfc5280#section-4.2.1.3
 87             * we must not verify a certificate signature if the key usage of
 88             * the CA certificate that issued the certificate prohibits signing.
 89             * In case the 'issuing' certificate is the last in the chain and is
 90             * not a CA certificate but a 'self-issued' end-entity cert (i.e.,
 91             * xs == xi && !(xi->ex_flags & EXFLAG_CA)) RFC 5280 does not apply
 92             * (see https://tools.ietf.org/html/rfc6818#section-2) and thus
 93             * we are free to ignore any key usage restrictions on such certs.
 94             */
 95            int ret = xs == xi && (xi->ex_flags & EXFLAG_CA) == 0
 96                ? X509_V_OK : ossl_x509_signing_allowed(xi, xs);
 97
 98            CB_FAIL_IF(ret != X509_V_OK, ctx, xi, issuer_depth, ret);
 99            // 获取公钥
100            if ((pkey = X509_get0_pubkey(xi)) == NULL) {
101                CB_FAIL_IF(1, ctx, xi, issuer_depth,
102                           X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY);
103            } else {
104                // 对证书的签名信息使用公钥做完整性校验
105                CB_FAIL_IF(X509_verify(xs, pkey) <= 0,
106                           ctx, xs, n, X509_V_ERR_CERT_SIGNATURE_FAILURE);
107            }
108        }
109
110        /* In addition to RFC 5280 requirements do also for trust anchor cert */
111        /* Calls verify callback as needed */
112        if (!ossl_x509_check_cert_time(ctx, xs, n))
113            return 0;
114
115        /*
116         * Signal success at this depth.  However, the previous error (if any)
117         * is retained.
118         */
119        ctx->current_issuer = xi;
120        ctx->current_cert = xs;
121        ctx->error_depth = n;
122        if (!ctx->verify_cb(1, ctx))
123            return 0;
124
125        if (--n >= 0) {
126            xi = xs;
127            xs = sk_X509_value(ctx->chain, n);
128        }
129    }
130    return 1;
131}