Pergunta

Eu tenho um aplicativo de trabalho que estabelece uma conexão SSL com um servidor. O servidor usa um certificado autoassinado e o cliente carrega uma cadeia de autoridade de certificação para dizer que o servidor está bem para confiar. Eu fiz isso com código como este no cliente:

SSL_METHOD* method = TLSv1_client_method();
_ctx = SSL_CTX_new(method);
if ( SSL_CTX_load_verify_locations(_ctx, "ca-all.crt", NULL) != 1 )
{
    return false;
}
_ssl = SSL_new(_ctx);
int val = SSL_set_fd(_ssl, _socket->GetFD());
if ( val != SSL_SUCCESS )
{
    int err = SSL_get_error(_ssl, val);
    return false;
}
val = SSL_connect(_ssl);

E no servidor:

  if ( SSL_CTX_use_certificate_chain_file( g_ctx, "ca-chain1.crt" ) <= 0 ) {
    return 1;
  }
  ppem_file = getenv( "PEM_FILE" );
  if ( ppem_file == NULL ) {
    ppem_file = pem_file;
  }
  if ( SSL_CTX_use_certificate_file( g_ctx, ppem_file,
                                     SSL_FILETYPE_PEM ) <= 0 ) {
    return 1;
  }
  if ( SSL_CTX_use_PrivateKey_file( g_ctx, ppem_file,
                                    SSL_FILETYPE_PEM ) <= 0 ) {
    return 2;
  }

Estou tentando modificar esse código para que o servidor também verifique o certificado de pares do cliente (auto-inscrito, usando o mesmo emissor que o servidor) e tendo um pouco de problemas. Não encontrei uma boa documentação "Visão geral conceitual" em nenhum lugar, e isso parece ser um obstáculo típico com as bibliotecas OpenSSL.

No cliente, adicionei isso após a chamada SSL_CTX_LOAD_VERIFY_LOCATIONS ():

if ( SSL_CTX_use_certificate_file(_ctx, "generic_client.pem", SSL_FILETYPE_PEM ) != 1 )
{
    return false;
}

No servidor, adicionei isso após a chamada SSL_CTX_USE_PRIVATEKEY_FILE ():

  STACK_OF(X509_NAME) *list;
  list = SSL_load_client_CA_file( "ca_chain2.crt" );
  if( list == NULL ) {
    return 4;
  }
  SSL_CTX_set_client_CA_list( g_ctx, list );
  SSL_CTX_set_verify( g_ctx, SSL_VERIFY_PEER, NULL );

A conexão falha porque o certificado não valida. O cliente parece carregar a multa do certificado e, se eu comentar a linha SSL_CTX_SET_VERIFY, o cliente se conecta sem problemas (porque seu certificado nunca foi verificado).

Parece que o servidor não pensa que a cadeia de autoridade de certificação do cliente é boa. O que estou perdendo aqui?

A partir da linha de comando que posso executar: OpenSSL verifique -CAfile Ca -Chain2.crt generic_client.pem e ele passa, por isso tenho os dados de certificado correto disponíveis, devo estar usando -o errado de alguma forma.

Foi útil?

Solução

No servidor, você também deve ligar SSL_CTX_load_verify_locations(). Esta função informa ao servidor quais certificados usar para verificação de certificados; a SSL_CTX_set_client_CA_list() A função define a lista de CAS permitidos que são enviados ao cliente no aperto de mão. Ambos são necessários.

(Você também precisa de um SSL_CTX_use_PrivateKey_file() ligue para o cliente, depois do use_certificate_file Ligue, mas acho que você está fazendo isso e deixou de fora).

Outras dicas

Ssl_ctx_set_client_ca_list define o Ca Lista. Um certificado de CA, por definição, é distinto de um certificado de usuário (por exemplo, ele tem o conjunto de bits CA). Por isso, recomendo que você crie um CA adequado (cujo certificado CA é auto-signitado) e use-o para assinar o cliente e o certificado do servidor. Suponho que o OpenSSL não espera que o cliente também use o certificado da CA para comunicação.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top