2018-08-28 :-|
_ 労
デバッグ労などをしました。
_ [TLS][SSL]サーバー証明書を指定しないと TLS ハンドシェイクでエラーになる件
ようするに Anonymous DH(ADH) を使うことになるうえにデフォルトだと OpenSSL は ADH を無効化しているのでハンドシェイクできません、ということらしい。
- In which cases can an SSL server omit sending the certificate? - Stack Overflow
- c++ - using SSL without certificate - Stack Overflow
- Is it safe to use HTTPS without SSL certificates for my own domains? - Stack Overflow
- The Transport Layer Security (TLS) Protocol Version 1.2 - A.5. The Cipher Suite
The following cipher suites are used for completely anonymous Diffie-Hellman communications in which neither party is authenticated. Note that this mode is vulnerable to man-in-the- middle attacks. Using this mode therefore is of limited use: These cipher suites MUST NOT be used by TLS 1.2 implementations unless the application layer has specifically requested to allow anonymous key exchange. (Anonymous key exchange may sometimes be acceptable, for example, to support opportunistic encryption when no set-up for authentication is in place, or when TLS is used as part of more complex security protocols that have other means to ensure authentication.) CipherSuite TLS_DH_anon_WITH_RC4_128_MD5 = { 0x00,0x18 }; CipherSuite TLS_DH_anon_WITH_3DES_EDE_CBC_SHA = { 0x00,0x1B }; CipherSuite TLS_DH_anon_WITH_AES_128_CBC_SHA = { 0x00,0x34 }; CipherSuite TLS_DH_anon_WITH_AES_256_CBC_SHA = { 0x00,0x3A }; CipherSuite TLS_DH_anon_WITH_AES_128_CBC_SHA256 = { 0x00,0x6C }; CipherSuite TLS_DH_anon_WITH_AES_256_CBC_SHA256 = { 0x00,0x6D };
たとえば Simple TLS Server - OpenSSLWiki というコードがあるじゃろ。
証明書と鍵を読む処理を #if 0 しておく。なお #include <string.h> を追加しないと strlen() で警告が出る。
#include <stdio.h> #include <unistd.h> #include <string.h> #include <sys/socket.h> #include <arpa/inet.h> #include <openssl/ssl.h> #include <openssl/err.h> int create_socket(int port) { int s; struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(port); addr.sin_addr.s_addr = htonl(INADDR_ANY); s = socket(AF_INET, SOCK_STREAM, 0); if (s < 0) { perror("Unable to create socket"); exit(EXIT_FAILURE); } if (bind(s, (struct sockaddr*)&addr, sizeof(addr)) < 0) { perror("Unable to bind"); exit(EXIT_FAILURE); } if (listen(s, 1) < 0) { perror("Unable to listen"); exit(EXIT_FAILURE); } return s; } void init_openssl() { SSL_load_error_strings(); OpenSSL_add_ssl_algorithms(); } void cleanup_openssl() { EVP_cleanup(); } SSL_CTX *create_context() { const SSL_METHOD *method; SSL_CTX *ctx; method = SSLv23_server_method(); ctx = SSL_CTX_new(method); if (!ctx) { perror("Unable to create SSL context"); ERR_print_errors_fp(stderr); exit(EXIT_FAILURE); } return ctx; } void configure_context(SSL_CTX *ctx) { SSL_CTX_set_ecdh_auto(ctx, 1); #if 0 /* Set the key and cert */ if (SSL_CTX_use_certificate_file(ctx, "/etc/ssl/myCA/ca.crt", SSL_FILETYPE_PEM) <= 0) { ERR_print_errors_fp(stderr); exit(EXIT_FAILURE); } if (SSL_CTX_use_PrivateKey_file(ctx, "/etc/ssl/myCA/private/ca.key", SSL_FILETYPE_PEM) <= 0 ) { ERR_print_errors_fp(stderr); exit(EXIT_FAILURE); } #endif } int main(int argc, char **argv) { int sock; SSL_CTX *ctx; init_openssl(); ctx = create_context(); configure_context(ctx); sock = create_socket(4433); /* Handle connections */ while(1) { struct sockaddr_in addr; uint len = sizeof(addr); SSL *ssl; const char reply[] = "test\n"; int client = accept(sock, (struct sockaddr*)&addr, &len); if (client < 0) { perror("Unable to accept"); exit(EXIT_FAILURE); } ssl = SSL_new(ctx); SSL_set_fd(ssl, client); if (SSL_accept(ssl) <= 0) { ERR_print_errors_fp(stderr); } else { SSL_write(ssl, reply, strlen(reply)); } SSL_free(ssl); close(client); } close(sock); SSL_CTX_free(ctx); cleanup_openssl(); }
ビルドして
gcc -g simple_tls_server.c -o simple_tls_server -L/usr/lib -I/usr/include -lssl -lcrypto
起動
% sudo ./simple_tls_server
クライアントから接続するとエラーになる。
% openssl s_client -connect localhost:4433 CONNECTED(00000003) 139649144783360:error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:ssl/record/rec_layer_s3.c:1407:SSL alert number 40 --- no peer certificate available --- No client certificate CA names sent --- SSL handshake has read 7 bytes and written 176 bytes Verification: OK --- New, (NONE), Cipher is (NONE) Secure Renegotiation IS NOT supported Compression: NONE Expansion: NONE No ALPN negotiated SSL-Session: Protocol : TLSv1.2 Cipher : 0000 Session-ID: Session-ID-ctx: Master-Key: PSK identity: None PSK identity hint: None SRP username: None Start Time: 1535423653 Timeout : 7200 (sec) Verify return code: 0 (ok) Extended master secret: no ---
サーバーはこんなことを言う。
139814337991168:error:1417A0C1:SSL routines:tls_post_process_client_hello:no shared cipher:ssl/statem/statem_srvr.c:1419:
[ツッコミを入れる]