質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

3727閲覧

SSL_readが初回1バイトしか読み込まない

whirota

総合スコア7

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2017/04/26 09:36

httpsサーバーを実装しています。
以下のコードをMacbook pro(OS:sierra)でコンパイル、動作させたところ、
googlechromeではSSL_readが1バイトだけしか読み込みません。
対策のご教授をお願いいたします。

///
cpp file
///
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/crypto.h>
int main(void)
{
SSL_CTX *ctx;
SSL *ssl;

int server, client, sd; int port = 8778 ; char crt_file[] = "server.crt"; char key_file[] = "server.key"; struct sockaddr_in addr; socklen_t size = sizeof(struct sockaddr_in); char buf[1024]={0}; char body[] = "hello world"; char header[] = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length: 11\r\nConnection: Close\r\n"; char msg[1024]; SSL_load_error_strings(); SSL_library_init(); OpenSSL_add_all_algorithms(); ctx = SSL_CTX_new(SSLv23_server_method()); SSL_CTX_use_certificate_file(ctx, crt_file, SSL_FILETYPE_PEM); SSL_CTX_use_PrivateKey_file(ctx, key_file, SSL_FILETYPE_PEM); server = socket(PF_INET, SOCK_STREAM, 0); bzero(&addr, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; addr.sin_port = htons(port); bind(server, (struct sockaddr*)&addr, sizeof(addr)); listen(server, 1); while(1) { memset(buf, 0, sizeof(buf)); client = accept(server, (struct sockaddr*)&addr, &size); printf( "Connection: %s:%d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port) ); ssl = SSL_new(ctx); SSL_set_fd(ssl, client); if (SSL_accept(ssl) > 0) { SSL_read(ssl, buf, sizeof(buf)); printf("request:%s\r\n", buf); snprintf(msg, sizeof(msg), "%s\r\n%s", header, body); SSL_write(ssl, msg, strlen(msg)); } sd = SSL_get_fd(ssl); SSL_free(ssl); close(sd); } close(server); SSL_CTX_free(ctx); return EXIT_SUCCESS;

}
/// makefile
CC=g++
OS=linux
CPPFLAGS=-Wall -O2 -fPIC -Wno-write-strings -std=c++0x -lpthread $(USR_FLG) -lcurl -lm /usr/lib/libssl.dylib -lm /usr/lib/libcrypto.dylib
PROGRAM=openssl.out
STRIP=strip
OBJS=openssl.o
INCPATH=-I/usr/local/opt/openssl/include

all:$(OBJS)
$(CC) $(OBJS) $(CPPFLAGS) -o $(PROGRAM)

.cpp.o:
$(CC) $(INCPATH) $(CPPFLAGS) -c $<

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

恐らく実験用に、 Chrome できちんと検証できないサーバ証明書 (所謂「オレオレ証明書」等) を使用しているのではないでしょうか? この場合 Chrome は、仮に例外として接続の続行を指示したとしても、最初のコネクションを証明書の検証直後に切断する実装になっているようです。
つまり、 Chrome 側の実装の問題で、ご呈示の HTTPS サーバの実装に問題があるわけでは無いと思います。対策としては、 Chrome を --ignore-certificate-errors コマンドラインオプション付きで起動するか、あるいは検証可能な正規のサーバ証明書を使用すると良いのではないでしょうか。

ちなみにこの動作については、 Chromium のソースコード中でも以下の通り、 HttpNetworkTransaction::OnCertificateError のコメントに言及されています。

HttpNetworkTransaction::OnCertificateError

cpp

1// TODO(mbelshe): For now, we're going to pass the error through, and that 2// will close the stream_request in all cases. This means that we're always 3// going to restart an entire STATE_CREATE_STREAM, even if the connection is 4// good and the user chooses to ignore the error. This is not ideal, but not 5// the end of the world either.

「理想的な動作ではないが、破滅的でもない」と仰ってますね。ここでそのまま、ユーザがそれを無視したいかに関わらず、受け取った SSL エラー値を HttpNetworkTransaction::OnIOComplete に渡してしまうため、最終的に HttpNetworkTransaction::ResetConnectionAndRequestForResend で一度コネクションが閉じてしまいます。

一度閉じてはしまいますが、検証に失敗した証明書は、初回のエラー処理時に以下の HttpStreamFactoryImpl::Job::HandleCertificateError の箇所で SSLConfig::allowed_bad_certs へと保存されています。そのため、ユーザの操作によって再度接続が続行された時には、エラーを無視して最後までリクエストが完了するようになっているようです。

HttpStreamFactoryImpl::Job::HandleCertificateError

投稿2017/05/05 11:44

argparse

総合スコア1017

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

whirota

2017/05/08 02:28

回答ありがとうございます。勉強になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問