📄 ssl_engine_vars.c
字号:
else if (ssl != NULL && strlen(var) > 7 && strcEQn(var, "CLIENT_", 7)) { if ((xs = SSL_get_peer_certificate(ssl)) != NULL) { result = ssl_var_lookup_ssl_cert(p, xs, var+7); X509_free(xs); } } else if (ssl != NULL && strlen(var) > 7 && strcEQn(var, "SERVER_", 7)) { if ((xs = SSL_get_certificate(ssl)) != NULL) { result = ssl_var_lookup_ssl_cert(p, xs, var+7); /* SSL_get_certificate() as of OpenSSL 0.9.7a does not increment the reference count the same way SSL_get_peer_certificate does, so no need to X509_free(xs) the stuff here. */ } } return result;}static char *ssl_var_lookup_ssl_cert(pool *p, X509 *xs, char *var){ char *result; BOOL resdup; X509_NAME *xsname; int nid; char *cp; result = NULL; resdup = TRUE; if (strcEQ(var, "M_VERSION")) { result = ap_psprintf(p, "%lu", X509_get_version(xs)+1); resdup = FALSE; } else if (strcEQ(var, "M_SERIAL")) { result = ssl_var_lookup_ssl_cert_serial(p, xs); } else if (strcEQ(var, "V_START")) { result = ssl_var_lookup_ssl_cert_valid(p, X509_get_notBefore(xs)); } else if (strcEQ(var, "V_END")) { result = ssl_var_lookup_ssl_cert_valid(p, X509_get_notAfter(xs)); } else if (strcEQ(var, "S_DN")) { xsname = X509_get_subject_name(xs); cp = X509_NAME_oneline(xsname, NULL, 0); result = ap_pstrdup(p, cp); OPENSSL_free(cp); resdup = FALSE; } else if (strlen(var) > 5 && strcEQn(var, "S_DN_", 5)) { xsname = X509_get_subject_name(xs); result = ssl_var_lookup_ssl_cert_dn(p, xsname, var+5); resdup = FALSE; } else if (strcEQ(var, "I_DN")) { xsname = X509_get_issuer_name(xs); cp = X509_NAME_oneline(xsname, NULL, 0); result = ap_pstrdup(p, cp); OPENSSL_free(cp); resdup = FALSE; } else if (strlen(var) > 5 && strcEQn(var, "I_DN_", 5)) { xsname = X509_get_issuer_name(xs); result = ssl_var_lookup_ssl_cert_dn(p, xsname, var+5); resdup = FALSE; } else if (strcEQ(var, "A_SIG")) { nid = OBJ_obj2nid(xs->cert_info->signature->algorithm); result = ap_pstrdup(p, (nid == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(nid)); resdup = FALSE; } else if (strcEQ(var, "A_KEY")) { nid = OBJ_obj2nid(xs->cert_info->key->algor->algorithm); result = ap_pstrdup(p, (nid == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(nid)); resdup = FALSE; } else if (strcEQ(var, "CERT")) { result = ssl_var_lookup_ssl_cert_PEM(p, xs); } if (result != NULL && resdup) result = ap_pstrdup(p, result); return result;}static const struct { char *name; int nid;} ssl_var_lookup_ssl_cert_dn_rec[] = { { "C", NID_countryName }, { "ST", NID_stateOrProvinceName }, /* officially (RFC2156) */ { "SP", NID_stateOrProvinceName }, /* compatibility (SSLeay) */ { "L", NID_localityName }, { "O", NID_organizationName }, { "OU", NID_organizationalUnitName }, { "CN", NID_commonName }, { "T", NID_title }, { "I", NID_initials }, { "G", NID_givenName }, { "S", NID_surname }, { "D", NID_description },#if SSL_LIBRARY_VERSION >= 0x00907000 { "UID", NID_x500UniqueIdentifier },#else { "UID", NID_uniqueIdentifier },#endif { "Email", NID_pkcs9_emailAddress }, { NULL, 0 }};static char *ssl_var_lookup_ssl_cert_dn(pool *p, X509_NAME *xsname, char *var){ char *result; X509_NAME_ENTRY *xsne; int i, j, n; result = NULL; for (i = 0; ssl_var_lookup_ssl_cert_dn_rec[i].name != NULL; i++) { if (strEQ(var, ssl_var_lookup_ssl_cert_dn_rec[i].name)) { for (j = 0; j < sk_X509_NAME_ENTRY_num(xsname->entries); j++) { xsne = sk_X509_NAME_ENTRY_value(xsname->entries, j); n = OBJ_obj2nid(xsne->object); if (n == ssl_var_lookup_ssl_cert_dn_rec[i].nid) { result = ap_palloc(p, xsne->value->length+1); ap_cpystrn(result, (char *)xsne->value->data, xsne->value->length+1);#ifdef CHARSET_EBCDIC ascii2ebcdic(result, result, xsne->value->length);#endif /* CHARSET_EBCDIC */ result[xsne->value->length] = NUL; break; } } break; } } return result;}static char *ssl_var_lookup_ssl_cert_valid(pool *p, ASN1_UTCTIME *tm){ char *result; BIO* bio; int n; if ((bio = BIO_new(BIO_s_mem())) == NULL) return NULL; ASN1_UTCTIME_print(bio, tm); n = BIO_pending(bio); result = ap_pcalloc(p, n+1); n = BIO_read(bio, result, n); result[n] = NUL; BIO_free(bio); return result;}static char *ssl_var_lookup_ssl_cert_serial(pool *p, X509 *xs){ char *result; BIO *bio; int n; if ((bio = BIO_new(BIO_s_mem())) == NULL) return NULL; i2a_ASN1_INTEGER(bio, X509_get_serialNumber(xs)); n = BIO_pending(bio); result = ap_pcalloc(p, n+1); n = BIO_read(bio, result, n); result[n] = NUL; BIO_free(bio); return result;}static char *ssl_var_lookup_ssl_cert_chain(pool *p, STACK_OF(X509) *sk, char *var){ char *result; X509 *xs; int n; result = NULL; if (strspn(var, "0123456789") == strlen(var)) { n = atoi(var); if (n < sk_X509_num(sk)) { xs = sk_X509_value(sk, n); result = ssl_var_lookup_ssl_cert_PEM(p, xs); } } return result;}static char *ssl_var_lookup_ssl_cert_PEM(pool *p, X509 *xs){ char *result; BIO *bio; int n; if ((bio = BIO_new(BIO_s_mem())) == NULL) return NULL; PEM_write_bio_X509(bio, xs); n = BIO_pending(bio); result = ap_pcalloc(p, n+1); n = BIO_read(bio, result, n); result[n] = NUL; BIO_free(bio); return result;}static char *ssl_var_lookup_ssl_cert_verify(pool *p, conn_rec *c){ char *result; long vrc; char *verr; char *vinfo; SSL *ssl; X509 *xs; result = NULL; ssl = ap_ctx_get(c->client->ctx, "ssl"); verr = ap_ctx_get(c->client->ctx, "ssl::verify::error"); vinfo = ap_ctx_get(c->client->ctx, "ssl::verify::info"); vrc = SSL_get_verify_result(ssl); xs = SSL_get_peer_certificate(ssl); if (vrc == X509_V_OK && verr == NULL && vinfo == NULL && xs == NULL) /* no client verification done at all */ result = "NONE"; else if (vrc == X509_V_OK && verr == NULL && vinfo == NULL && xs != NULL) /* client verification done successful */ result = "SUCCESS"; else if (vrc == X509_V_OK && vinfo != NULL && strEQ(vinfo, "GENEROUS")) /* client verification done in generous way */ result = "GENEROUS"; else /* client verification failed */ result = ap_psprintf(p, "FAILED:%s", verr); if (xs != NULL) X509_free(xs); return result;}static char *ssl_var_lookup_ssl_cipher(pool *p, conn_rec *c, char *var){ char *result; BOOL resdup; int usekeysize, algkeysize; SSL *ssl; result = NULL; resdup = TRUE; ssl = ap_ctx_get(c->client->ctx, "ssl"); ssl_var_lookup_ssl_cipher_bits(ssl, &usekeysize, &algkeysize); if (strEQ(var, "")) result = (ssl != NULL ? (char *)SSL_get_cipher_name(ssl) : NULL); else if (strcEQ(var, "_EXPORT")) result = (usekeysize < 56 ? "true" : "false"); else if (strcEQ(var, "_USEKEYSIZE")) { result = ap_psprintf(p, "%d", usekeysize); resdup = FALSE; } else if (strcEQ(var, "_ALGKEYSIZE")) { result = ap_psprintf(p, "%d", algkeysize); resdup = FALSE; } if (result != NULL && resdup) result = ap_pstrdup(p, result); return result;}static void ssl_var_lookup_ssl_cipher_bits(SSL *ssl, int *usekeysize, int *algkeysize){ SSL_CIPHER *cipher; *usekeysize = 0; *algkeysize = 0; if (ssl != NULL) if ((cipher = SSL_get_current_cipher(ssl)) != NULL) *usekeysize = SSL_CIPHER_get_bits(cipher, algkeysize); return;}static char *ssl_var_lookup_ssl_version(pool *p, char *var){ char *result; char *cp, *cp2; result = NULL; if (strEQ(var, "PRODUCT")) {#if defined(SSL_PRODUCT_NAME) && defined(SSL_PRODUCT_VERSION) result = ap_psprintf(p, "%s/%s", SSL_PRODUCT_NAME, SSL_PRODUCT_VERSION);#else result = NULL;#endif } else if (strEQ(var, "INTERFACE")) { result = ap_psprintf(p, "mod_ssl/%s", MOD_SSL_VERSION); } else if (strEQ(var, "LIBRARY")) { result = ap_pstrdup(p, SSL_LIBRARY_TEXT); if ((cp = strchr(result, ' ')) != NULL) { *cp = '/'; if ((cp2 = strchr(cp, ' ')) != NULL) *cp2 = NUL; } } return result;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -