📄 tls_openssl.c
字号:
wpa_printf(MSG_DEBUG, "OpenSSL: %s - loaded " "DER format CA certificate", __func__); } else return -1; } else { wpa_printf(MSG_DEBUG, "TLS: Trusted root " "certificate(s) loaded"); tls_get_errors(ssl_ctx); } SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb);#else /* OPENSSL_NO_STDIO */ wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO", __func__); return -1;#endif /* OPENSSL_NO_STDIO */ } else { /* No ca_cert configured - do not try to verify server * certificate */ SSL_set_verify(conn->ssl, SSL_VERIFY_NONE, NULL); } return 0;}static int tls_global_ca_cert(SSL_CTX *ssl_ctx, const char *ca_cert){ if (ca_cert) { if (SSL_CTX_load_verify_locations(ssl_ctx, ca_cert, NULL) != 1) { tls_show_errors(MSG_WARNING, __func__, "Failed to load root certificates"); return -1; } wpa_printf(MSG_DEBUG, "TLS: Trusted root " "certificate(s) loaded");#ifndef OPENSSL_NO_STDIO /* Add the same CAs to the client certificate requests */ SSL_CTX_set_client_CA_list(ssl_ctx, SSL_load_client_CA_file(ca_cert));#endif /* OPENSSL_NO_STDIO */ } return 0;}int tls_global_set_verify(void *ssl_ctx, int check_crl){ int flags; if (check_crl) { X509_STORE *cs = SSL_CTX_get_cert_store(ssl_ctx); if (cs == NULL) { tls_show_errors(MSG_INFO, __func__, "Failed to get " "certificate store when enabling " "check_crl"); return -1; } flags = X509_V_FLAG_CRL_CHECK; if (check_crl == 2) flags |= X509_V_FLAG_CRL_CHECK_ALL; X509_STORE_set_flags(cs, flags); } return 0;}static int tls_connection_set_subject_match(struct tls_connection *conn, const char *subject_match, const char *altsubject_match){ free(conn->subject_match); conn->subject_match = NULL; if (subject_match) { conn->subject_match = strdup(subject_match); if (conn->subject_match == NULL) return -1; } free(conn->altsubject_match); conn->altsubject_match = NULL; if (altsubject_match) { conn->altsubject_match = strdup(altsubject_match); if (conn->altsubject_match == NULL) return -1; } return 0;}int tls_connection_set_verify(void *ssl_ctx, struct tls_connection *conn, int verify_peer){ if (conn == NULL) return -1; if (verify_peer) { SSL_set_verify(conn->ssl, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT | SSL_VERIFY_CLIENT_ONCE, tls_verify_cb); } else { SSL_set_verify(conn->ssl, SSL_VERIFY_NONE, NULL); } SSL_set_accept_state(conn->ssl); return 0;}static int tls_connection_client_cert(struct tls_connection *conn, const char *client_cert, const u8 *client_cert_blob, size_t client_cert_blob_len){ if (client_cert == NULL && client_cert_blob == NULL) return 0; if (client_cert_blob && SSL_use_certificate_ASN1(conn->ssl, (u8 *) client_cert_blob, client_cert_blob_len) == 1) { wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_certificate_ASN1 --> " "OK"); return 0; } else if (client_cert_blob) { tls_show_errors(MSG_DEBUG, __func__, "SSL_use_certificate_ASN1 failed"); } if (client_cert == NULL) return -1;#ifndef OPENSSL_NO_STDIO if (SSL_use_certificate_file(conn->ssl, client_cert, SSL_FILETYPE_ASN1) == 1) { wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_certificate_file (DER)" " --> OK"); return 0; } else { tls_show_errors(MSG_DEBUG, __func__, "SSL_use_certificate_file (DER) failed"); } if (SSL_use_certificate_file(conn->ssl, client_cert, SSL_FILETYPE_PEM) == 1) { wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_certificate_file (PEM)" " --> OK"); return 0; } else { tls_show_errors(MSG_DEBUG, __func__, "SSL_use_certificate_file (PEM) failed"); }#else /* OPENSSL_NO_STDIO */ wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO", __func__);#endif /* OPENSSL_NO_STDIO */ return -1;}static int tls_global_client_cert(SSL_CTX *ssl_ctx, const char *client_cert){#ifndef OPENSSL_NO_STDIO if (client_cert == NULL) return 0; if (SSL_CTX_use_certificate_file(ssl_ctx, client_cert, SSL_FILETYPE_ASN1) != 1 && SSL_CTX_use_certificate_file(ssl_ctx, client_cert, SSL_FILETYPE_PEM) != 1) { tls_show_errors(MSG_INFO, __func__, "Failed to load client certificate"); return -1; } return 0;#else /* OPENSSL_NO_STDIO */ if (client_cert == NULL) return 0; wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO", __func__); return -1;#endif /* OPENSSL_NO_STDIO */}static int tls_passwd_cb(char *buf, int size, int rwflag, void *password){ if (password == NULL) { return 0; } strncpy(buf, (char *) password, size); buf[size - 1] = '\0'; return strlen(buf);}#ifdef PKCS12_FUNCSstatic int tls_parse_pkcs12(SSL_CTX *ssl_ctx, SSL *ssl, PKCS12 *p12, const char *passwd){ EVP_PKEY *pkey; X509 *cert; STACK_OF(X509) *certs; int res = 0; char buf[256]; pkey = NULL; cert = NULL; certs = NULL; if (!PKCS12_parse(p12, passwd, &pkey, &cert, &certs)) { tls_show_errors(MSG_DEBUG, __func__, "Failed to parse PKCS12 file"); PKCS12_free(p12); return -1; } wpa_printf(MSG_DEBUG, "TLS: Successfully parsed PKCS12 data"); if (cert) { X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf)); wpa_printf(MSG_DEBUG, "TLS: Got certificate from PKCS12: " "subject='%s'", buf); if (ssl) { if (SSL_use_certificate(ssl, cert) != 1) res = -1; } else { if (SSL_CTX_use_certificate(ssl_ctx, cert) != 1) res = -1; } X509_free(cert); } if (pkey) { wpa_printf(MSG_DEBUG, "TLS: Got private key from PKCS12"); if (ssl) { if (SSL_use_PrivateKey(ssl, pkey) != 1) res = -1; } else { if (SSL_CTX_use_PrivateKey(ssl_ctx, pkey) != 1) res = -1; } EVP_PKEY_free(pkey); } if (certs) { while ((cert = sk_X509_pop(certs)) != NULL) { X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf)); wpa_printf(MSG_DEBUG, "TLS: additional certificate" " from PKCS12: subject='%s'", buf); /* * There is no SSL equivalent for the chain cert - so * always add it to the context... */ if (SSL_CTX_add_extra_chain_cert(ssl_ctx, cert) != 1) { res = -1; break; } } sk_X509_free(certs); } PKCS12_free(p12); if (res < 0) tls_get_errors(ssl_ctx); return res;}#endif /* PKCS12_FUNCS */static int tls_read_pkcs12(SSL_CTX *ssl_ctx, SSL *ssl, const char *private_key, const char *passwd){#ifdef PKCS12_FUNCS FILE *f; PKCS12 *p12; f = fopen(private_key, "r"); if (f == NULL) return -1; p12 = d2i_PKCS12_fp(f, NULL); fclose(f); if (p12 == NULL) { tls_show_errors(MSG_INFO, __func__, "Failed to use PKCS#12 file"); return -1; } return tls_parse_pkcs12(ssl_ctx, ssl, p12, passwd);#else /* PKCS12_FUNCS */ wpa_printf(MSG_INFO, "TLS: PKCS12 support disabled - cannot read " "p12/pfx files"); return -1;#endif /* PKCS12_FUNCS */}static int tls_read_pkcs12_blob(SSL_CTX *ssl_ctx, SSL *ssl, const u8 *blob, size_t len, const char *passwd){#ifdef PKCS12_FUNCS PKCS12 *p12; p12 = d2i_PKCS12(NULL, (OPENSSL_d2i_TYPE) &blob, len); if (p12 == NULL) { tls_show_errors(MSG_INFO, __func__, "Failed to use PKCS#12 blob"); return -1; } return tls_parse_pkcs12(ssl_ctx, ssl, p12, passwd);#else /* PKCS12_FUNCS */ wpa_printf(MSG_INFO, "TLS: PKCS12 support disabled - cannot parse " "p12/pfx blobs"); return -1;#endif /* PKCS12_FUNCS */}static int tls_connection_engine_private_key(struct tls_connection *conn){#ifndef OPENSSL_NO_ENGINE if (SSL_use_PrivateKey(conn->ssl, conn->private_key) != 1) { tls_show_errors(MSG_ERROR, __func__, "ENGINE: cannot use private key for TLS"); return -1; } if (!SSL_check_private_key(conn->ssl)) { tls_show_errors(MSG_INFO, __func__, "Private key failed verification"); return -1; } return 0;#else /* OPENSSL_NO_ENGINE */ wpa_printf(MSG_ERROR, "SSL: Configuration uses engine, but " "engine support was not compiled in"); return -1;#endif /* OPENSSL_NO_ENGINE */}static int tls_connection_private_key(void *_ssl_ctx, struct tls_connection *conn, const char *private_key, const char *private_key_passwd, const u8 *private_key_blob, size_t private_key_blob_len){ SSL_CTX *ssl_ctx = _ssl_ctx; char *passwd; int ok; if (private_key == NULL && private_key_blob == NULL) return 0; if (private_key_passwd) { passwd = strdup(private_key_passwd); if (passwd == NULL) return -1; } else passwd = NULL; SSL_CTX_set_default_passwd_cb(ssl_ctx, tls_passwd_cb); SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, passwd); ok = 0; while (private_key_blob) { if (SSL_use_PrivateKey_ASN1(EVP_PKEY_RSA, conn->ssl, (u8 *) private_key_blob, private_key_blob_len) == 1) { wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_PrivateKey_" "ASN1(EVP_PKEY_RSA) --> OK"); ok = 1; break; } else { tls_show_errors(MSG_DEBUG, __func__, "SSL_use_PrivateKey_ASN1(EVP_PKEY_RSA)" " failed"); } if (SSL_use_PrivateKey_ASN1(EVP_PKEY_DSA, conn->ssl, (u8 *) private_key_blob, private_key_blob_len) == 1) { wpa_printf(MSG_DEBUG, "OpenSSL: SSL_use_PrivateKey_" "ASN1(EVP_PKEY_DSA) --> OK"); ok = 1; break; } else { tls_show_errors(MSG_DEBUG, __func__, "SSL_use_PrivateKey_ASN1(EVP_PKEY_DSA)" " failed"); } if (SSL_use_RSAPrivateKey_ASN1(conn->ssl, (u8 *) private_key_blob, private_key_blob_len) == 1) { wpa_printf(MSG_DEBUG, "OpenSSL: " "SSL_use_RSAPrivateKey_ASN1 --> OK"); ok = 1; break; } else { tls_show_errors(MSG_DEBUG, __func__, "SSL_use_RSAPrivateKey_ASN1 failed"); } if (tls_read_pkcs12_blob(ssl_ctx, conn->ssl, private_key_blob, private_key_blob_len, passwd) == 0) { wpa_printf(MSG_DEBUG, "OpenSSL: PKCS#12 as blob --> " "OK"); ok = 1; break; } break; } while (!ok && private_key) {#ifndef OPENSSL_NO_STDIO if (SSL_use_PrivateKey_file(conn->ssl, private_key, SSL_FILETYPE_ASN1) == 1) { wpa_printf(MSG_DEBUG, "OpenSSL: " "SSL_use_PrivateKey_File (DER) --> OK"); ok = 1; break; } else { tls_show_errors(MSG_DEBUG, __func__, "SSL_use_PrivateKey_File (DER) " "failed"); } if (SSL_use_PrivateKey_file(conn->ssl, private_key, SSL_FILETYPE_PEM) == 1) { wpa_printf(MSG_DEBUG, "OpenSSL: " "SSL_use_PrivateKey_File (PEM) --> OK"); ok = 1; break; } else { tls_show_errors(MSG_DEBUG, __func__, "SSL_use_PrivateKey_File (PEM) " "failed"); }#else /* OPENSSL_NO_STDIO */ wpa_printf(MSG_DEBUG, "OpenSSL: %s - OPENSSL_NO_STDIO", __func__);#endif /* OPENSSL_NO_STDIO */ if (tls_read_pkcs12(ssl_ctx, conn->ssl, private_key, passwd) == 0) { wpa_printf(MSG_DEBUG, "OpenSSL: Reading PKCS#12 file " "--> OK"); ok = 1; break; } if (tls_cryptoapi_cert(conn->ssl, private_key) == 0) { wpa_printf(MSG_DEBUG, "OpenSSL: Using CryptoAPI to " "access certificate store --> OK"); ok = 1; break; } break; } if (!ok) { wpa_printf(MSG_INFO, "OpenSSL: Failed to load private key"); free(passwd); ERR_clear_error(); return -1; } ERR_clear_error(); SSL_CTX_set_default_passwd_cb(ssl_ctx, NULL); free(passwd); if (!SSL_check_private_key(conn->ssl)) { tls_show_errors(MSG_INFO, __func__, "Private key failed " "verification"); return -1; } wpa_printf(MSG_DEBUG, "SSL: Private key loaded successfully"); return 0;}static int tls_global_private_key(SSL_CTX *ssl_ctx, const char *private_key, const char *private_key_passwd){ char *passwd; if (private_key == NULL) return 0; if (private_key_passwd) { passwd = strdup(private_key_passwd); if (passwd == NULL) return -1; } else passwd = NULL; SSL_CTX_set_default_passwd_cb(ssl_ctx, tls_passwd_cb); SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, passwd); if (#ifndef OPENSSL_NO_STDIO SSL_CTX_use_PrivateKey_file(ssl_ctx, private_key, SSL_FILETYPE_ASN1) != 1 && SSL_CTX_use_PrivateKey_file(ssl_ctx, private_key, SSL_FILETYPE_PEM) != 1 &&#endif /* OPENSSL_NO_STDIO */ tls_read_pkcs12(ssl_ctx, NULL, private_key, passwd)) { tls_show_errors(MSG_INFO, __func__, "Failed to load private key"); free(passwd); ERR_clear_error(); return -1; } free(passwd); ERR_clear_error(); SSL_CTX_set_default_passwd_cb(ssl_ctx, NULL); if (!SSL_CTX_check_private_key(ssl_ctx)) { tls_show_errors(MSG_INFO, __func__, "Private key failed verification"); return -1; } return 0;}static int tls_connection_dh(struct tls_connection *conn, const char *dh_file){#ifdef OPENSSL_NO_DH if (dh_file == NULL) return 0; wpa_printf(MSG_ERROR, "TLS: openssl does not include DH support, but " "dh_file specified"); return -1;#else /* OPENSSL_NO_DH */ DH *dh; BIO *bio; /* TODO: add support for dh_blob */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -