Beispiel #1
0
/*
 * check peer cert against CRL
 */
result_t
x509_verify_crl(const char *crl_file, x509_cert *cert, const char *subject)
{
  result_t retval = FAILURE;
  x509_crl crl = {0};

  if (x509parse_crlfile(&crl, crl_file) != 0)
    {
      msg (M_ERR, "CRL: cannot read CRL from file %s", crl_file);
      goto end;
    }

  if(cert->issuer_raw.len != crl.issuer_raw.len ||
      memcmp(crl.issuer_raw.p, cert->issuer_raw.p, crl.issuer_raw.len) != 0)
    {
      msg (M_WARN, "CRL: CRL %s is from a different issuer than the issuer of "
	  "certificate %s", crl_file, subject);
      retval = SUCCESS;
      goto end;
    }

  if (0 != x509parse_revoked(cert, &crl))
    {
      msg (D_HANDSHAKE, "CRL CHECK FAILED: %s is REVOKED", subject);
      goto end;
    }

  retval = SUCCESS;
  msg (D_HANDSHAKE, "CRL CHECK OK: %s",subject);

end:
  x509_crl_free(&crl);
  return retval;
}
Beispiel #2
0
void Curl_polarssl_close(struct connectdata *conn, int sockindex)
{
  rsa_free(&conn->ssl[sockindex].rsa);
  x509_free(&conn->ssl[sockindex].clicert);
  x509_free(&conn->ssl[sockindex].cacert);
  x509_crl_free(&conn->ssl[sockindex].crl);
  ssl_free(&conn->ssl[sockindex].ssl);
}
Beispiel #3
0
static void Curl_polarssl_close(struct connectdata *conn, int sockindex)
{
  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
  rsa_free(&BACKEND->rsa);
  x509_crt_free(&BACKEND->clicert);
  x509_crt_free(&BACKEND->cacert);
  x509_crl_free(&BACKEND->crl);
  ssl_free(&BACKEND->ssl);
}
/*
 * check peer cert against CRL
 */
result_t
x509_verify_crl(const char *crl_file, const char* crl_inline,
                x509_crt *cert, const char *subject)
{
  result_t retval = FAILURE;
  x509_crl crl = {0};
  struct gc_arena gc = gc_new();
  char *serial;

  if (!strcmp (crl_file, INLINE_FILE_TAG) && crl_inline)
    {
      if (!polar_ok(x509_crl_parse(&crl, crl_inline, strlen(crl_inline))))
        {
           msg (M_WARN, "CRL: cannot parse inline CRL");
           goto end;
        }
    }
  else
    {
      if (!polar_ok(x509_crl_parse_file(&crl, crl_file)))
      {
          msg (M_WARN, "CRL: cannot read CRL from file %s", crl_file);
          goto end;
      }
  }

  if(cert->issuer_raw.len != crl.issuer_raw.len ||
      memcmp(crl.issuer_raw.p, cert->issuer_raw.p, crl.issuer_raw.len) != 0)
    {
      msg (M_WARN, "CRL: CRL %s is from a different issuer than the issuer of "
	  "certificate %s", crl_file, subject);
      retval = SUCCESS;
      goto end;
    }

  if (!polar_ok(x509_crt_revoked(cert, &crl)))
    {
      serial = backend_x509_get_serial_hex(cert, &gc);
      msg (D_HANDSHAKE, "CRL CHECK FAILED: %s (serial %s) is REVOKED", subject, (serial ? serial : "NOT AVAILABLE"));
      goto end;
    }

  retval = SUCCESS;
  msg (D_HANDSHAKE, "CRL CHECK OK: %s",subject);

end:
  gc_free(&gc);
  x509_crl_free(&crl);
  return retval;
}
/*
 * check peer cert against CRL
 */
result_t
x509_verify_crl(const char *crl_file, x509_crt *cert, const char *subject)
{
  result_t retval = FAILURE;
  x509_crl crl = {0};
  struct gc_arena gc = gc_new();
  char *serial;

  int polar_retval = x509_crl_parse_file(&crl, crl_file);
  if (polar_retval != 0)
    {
      char errstr[128];
      polarssl_strerror(polar_retval, errstr, sizeof(errstr));
      msg (M_WARN, "CRL: cannot read CRL from file %s (%s)", crl_file, errstr);
      goto end;
    }

  if(cert->issuer_raw.len != crl.issuer_raw.len ||
      memcmp(crl.issuer_raw.p, cert->issuer_raw.p, crl.issuer_raw.len) != 0)
    {
      msg (M_WARN, "CRL: CRL %s is from a different issuer than the issuer of "
	  "certificate %s", crl_file, subject);
      retval = SUCCESS;
      goto end;
    }

  if (0 != x509_crt_revoked(cert, &crl))
    {
      serial = backend_x509_get_serial_hex(cert, &gc);
      msg (D_HANDSHAKE, "CRL CHECK FAILED: %s (serial %s) is REVOKED", subject, (serial ? serial : "NOT AVAILABLE"));
      goto end;
    }

  retval = SUCCESS;
  msg (D_HANDSHAKE, "CRL CHECK OK: %s",subject);

end:
  gc_free(&gc);
  x509_crl_free(&crl);
  return retval;
}
Beispiel #6
0
void
ngx_ssl_cleanup_ctx(void *data)
{
    ngx_ssl_t  *ssl = data;

    if (ssl->ciphersuites != NULL) {
        ngx_free(ssl->ciphersuites);
    }

    dhm_free(&ssl->dhm_ctx);
    if (ssl->have_own_cert) {
        x509_free(&ssl->own_cert);
        rsa_free(&ssl->own_key);
    }
    if (ssl->have_ca_cert) {
        x509_free(&ssl->ca_cert);
    }
    if (ssl->have_ca_crl) {
        x509_crl_free(&ssl->ca_crl);
    }
}
Beispiel #7
0
int main( int argc, char *argv[] )
{
    int ret = 0;
    unsigned char buf[1024];
    x509_crl crl;
    int i, j, n;
    char *p, *q;

    /*
     * Set to sane values
     */
    memset( &crl, 0, sizeof( x509_crl ) );

    if( argc == 0 )
    {
usage:
        printf( USAGE );
        goto exit;
    }

    opt.filename            = DFL_FILENAME;
    opt.debug_level         = DFL_DEBUG_LEVEL;

    for( i = 1; i < argc; i++ )
    {
        n = strlen( argv[i] );

        for( j = 0; j < n; j++ )
        {
            if( argv[i][j] >= 'A' && argv[i][j] <= 'Z' )
                argv[i][j] |= 0x20;
        }

        p = argv[i];
        if( ( q = strchr( p, '=' ) ) == NULL )
            goto usage;
        *q++ = '\0';

        if( strcmp( p, "filename" ) == 0 )
            opt.filename = q;
        else if( strcmp( p, "debug_level" ) == 0 )
        {
            opt.debug_level = atoi( q );
            if( opt.debug_level < 0 || opt.debug_level > 65535 )
                goto usage;
        }
        else
            goto usage;
    }

    /*
     * 1.1. Load the CRL
     */
    printf( "\n  . Loading the CRL ..." );
    fflush( stdout );

    ret = x509parse_crlfile( &crl, opt.filename );

    if( ret != 0 )
    {
        printf( " failed\n  !  x509parse_crl returned %d\n\n", ret );
        x509_crl_free( &crl );
        goto exit;
    }

    printf( " ok\n" );

    /*
     * 1.2 Print the CRL
     */
    printf( "  . CRL information    ...\n" );
    ret = x509parse_crl_info( (char *) buf, sizeof( buf ) - 1, "      ", &crl );
    if( ret == -1 )
    {
        printf( " failed\n  !  x509parse_crl_info returned %d\n\n", ret );
        x509_crl_free( &crl );
        goto exit;
    }

    printf( "%s\n", buf );

exit:
    x509_crl_free( &crl );

#ifdef WIN32
    printf( "  + Press Enter to exit this program.\n" );
    fflush( stdout );
    getchar();
#endif

    return( ret );
}
Beispiel #8
0
/*
 * Parse one  CRLs in DER format and append it to the chained list
 */
int x509_crl_parse_der( x509_crl *chain,
                        const unsigned char *buf, size_t buflen )
{
    int ret;
    size_t len;
    unsigned char *p, *end;
    x509_buf sig_params1, sig_params2;
    x509_crl *crl = chain;

    /*
     * Check for valid input
     */
    if( crl == NULL || buf == NULL )
        return( POLARSSL_ERR_X509_BAD_INPUT_DATA );

    memset( &sig_params1, 0, sizeof( x509_buf ) );
    memset( &sig_params2, 0, sizeof( x509_buf ) );

    /*
     * Add new CRL on the end of the chain if needed.
     */
    while( crl->version != 0 && crl->next != NULL )
        crl = crl->next;

    if( crl->version != 0 && crl->next == NULL )
    {
        crl->next = polarssl_malloc( sizeof( x509_crl ) );

        if( crl->next == NULL )
        {
            x509_crl_free( crl );
            return( POLARSSL_ERR_X509_MALLOC_FAILED );
        }

        x509_crl_init( crl->next );
        crl = crl->next;
    }

    /*
     * Copy raw DER-encoded CRL
     */
    if( ( p = polarssl_malloc( buflen ) ) == NULL )
        return( POLARSSL_ERR_X509_MALLOC_FAILED );

    memcpy( p, buf, buflen );

    crl->raw.p = p;
    crl->raw.len = buflen;

    end = p + buflen;

    /*
     * CertificateList  ::=  SEQUENCE  {
     *      tbsCertList          TBSCertList,
     *      signatureAlgorithm   AlgorithmIdentifier,
     *      signatureValue       BIT STRING  }
     */
    if( ( ret = asn1_get_tag( &p, end, &len,
            ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
    {
        x509_crl_free( crl );
        return( POLARSSL_ERR_X509_INVALID_FORMAT );
    }

    if( len != (size_t) ( end - p ) )
    {
        x509_crl_free( crl );
        return( POLARSSL_ERR_X509_INVALID_FORMAT +
                POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
    }

    /*
     * TBSCertList  ::=  SEQUENCE  {
     */
    crl->tbs.p = p;

    if( ( ret = asn1_get_tag( &p, end, &len,
            ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
    {
        x509_crl_free( crl );
        return( POLARSSL_ERR_X509_INVALID_FORMAT + ret );
    }

    end = p + len;
    crl->tbs.len = end - crl->tbs.p;

    /*
     * Version  ::=  INTEGER  OPTIONAL {  v1(0), v2(1)  }
     *               -- if present, MUST be v2
     *
     * signature            AlgorithmIdentifier
     */
    if( ( ret = x509_crl_get_version( &p, end, &crl->version ) ) != 0 ||
        ( ret = x509_get_alg( &p, end, &crl->sig_oid1, &sig_params1 ) ) != 0 )
    {
        x509_crl_free( crl );
        return( ret );
    }

    crl->version++;

    if( crl->version > 2 )
    {
        x509_crl_free( crl );
        return( POLARSSL_ERR_X509_UNKNOWN_VERSION );
    }

    if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &sig_params1,
                                  &crl->sig_md, &crl->sig_pk,
                                  &crl->sig_opts ) ) != 0 )
    {
        x509_crl_free( crl );
        return( POLARSSL_ERR_X509_UNKNOWN_SIG_ALG );
    }

    /*
     * issuer               Name
     */
    crl->issuer_raw.p = p;

    if( ( ret = asn1_get_tag( &p, end, &len,
            ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
    {
        x509_crl_free( crl );
        return( POLARSSL_ERR_X509_INVALID_FORMAT + ret );
    }

    if( ( ret = x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
    {
        x509_crl_free( crl );
        return( ret );
    }

    crl->issuer_raw.len = p - crl->issuer_raw.p;

    /*
     * thisUpdate          Time
     * nextUpdate          Time OPTIONAL
     */
    if( ( ret = x509_get_time( &p, end, &crl->this_update ) ) != 0 )
    {
        x509_crl_free( crl );
        return( ret );
    }

    if( ( ret = x509_get_time( &p, end, &crl->next_update ) ) != 0 )
    {
        if( ret != ( POLARSSL_ERR_X509_INVALID_DATE +
                        POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) &&
            ret != ( POLARSSL_ERR_X509_INVALID_DATE +
                        POLARSSL_ERR_ASN1_OUT_OF_DATA ) )
        {
            x509_crl_free( crl );
            return( ret );
        }
    }

    /*
     * revokedCertificates    SEQUENCE OF SEQUENCE   {
     *      userCertificate        CertificateSerialNumber,
     *      revocationDate         Time,
     *      crlEntryExtensions     Extensions OPTIONAL
     *                                   -- if present, MUST be v2
     *                        } OPTIONAL
     */
    if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
    {
        x509_crl_free( crl );
        return( ret );
    }

    /*
     * crlExtensions          EXPLICIT Extensions OPTIONAL
     *                              -- if present, MUST be v2
     */
    if( crl->version == 2 )
    {
        ret = x509_get_crl_ext( &p, end, &crl->crl_ext );

        if( ret != 0 )
        {
            x509_crl_free( crl );
            return( ret );
        }
    }

    if( p != end )
    {
        x509_crl_free( crl );
        return( POLARSSL_ERR_X509_INVALID_FORMAT +
                POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
    }

    end = crl->raw.p + crl->raw.len;

    /*
     *  signatureAlgorithm   AlgorithmIdentifier,
     *  signatureValue       BIT STRING
     */
    if( ( ret = x509_get_alg( &p, end, &crl->sig_oid2, &sig_params2 ) ) != 0 )
    {
        x509_crl_free( crl );
        return( ret );
    }

    if( crl->sig_oid1.len != crl->sig_oid2.len ||
        memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 ||
        sig_params1.len != sig_params2.len ||
        ( sig_params1.len != 0 &&
          memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 ) )
    {
        x509_crl_free( crl );
        return( POLARSSL_ERR_X509_SIG_MISMATCH );
    }

    if( ( ret = x509_get_sig( &p, end, &crl->sig ) ) != 0 )
    {
        x509_crl_free( crl );
        return( ret );
    }

    if( p != end )
    {
        x509_crl_free( crl );
        return( POLARSSL_ERR_X509_INVALID_FORMAT +
                POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
    }

    return( 0 );
}
Beispiel #9
0
int main( int argc, char *argv[] )
{
    int ret = 0;
    unsigned char buf[100000];
    x509_crl crl;
    int i;
    char *p, *q;

    /*
     * Set to sane values
     */
    x509_crl_init( &crl );

    if( argc == 0 )
    {
usage:
        polarssl_printf( USAGE );
        goto exit;
    }

    opt.filename            = DFL_FILENAME;

    for( i = 1; i < argc; i++ )
    {
        p = argv[i];
        if( ( q = strchr( p, '=' ) ) == NULL )
            goto usage;
        *q++ = '\0';

        if( strcmp( p, "filename" ) == 0 )
            opt.filename = q;
        else
            goto usage;
    }

    /*
     * 1.1. Load the CRL
     */
    polarssl_printf( "\n  . Loading the CRL ..." );
    fflush( stdout );

    ret = x509_crl_parse_file( &crl, opt.filename );

    if( ret != 0 )
    {
        polarssl_printf( " failed\n  !  x509_crl_parse_file returned %d\n\n", ret );
        x509_crl_free( &crl );
        goto exit;
    }

    polarssl_printf( " ok\n" );

    /*
     * 1.2 Print the CRL
     */
    polarssl_printf( "  . CRL information    ...\n" );
    ret = x509_crl_info( (char *) buf, sizeof( buf ) - 1, "      ", &crl );
    if( ret == -1 )
    {
        polarssl_printf( " failed\n  !  x509_crl_info returned %d\n\n", ret );
        x509_crl_free( &crl );
        goto exit;
    }

    polarssl_printf( "%s\n", buf );

exit:
    x509_crl_free( &crl );

#if defined(_WIN32)
    polarssl_printf( "  + Press Enter to exit this program.\n" );
    fflush( stdout );
    getchar();
#endif

    return( ret );
}
Beispiel #10
0
int main( int argc, char *argv[] )
{
    int ret = 0, server_fd;
    unsigned char buf[1024];
    entropy_context entropy;
    ctr_drbg_context ctr_drbg;
    ssl_context ssl;
    x509_crt cacert;
    x509_crt clicert;
    x509_crl cacrl;
    pk_context pkey;
    int i, j;
    int flags, verify = 0;
    char *p, *q;
    const char *pers = "cert_app";

    /*
     * Set to sane values
     */
    server_fd = 0;
    x509_crt_init( &cacert );
    x509_crt_init( &clicert );
#if defined(POLARSSL_X509_CRL_PARSE_C)
    x509_crl_init( &cacrl );
#else
    /* Zeroize structure as CRL parsing is not supported and we have to pass
       it to the verify function */
    memset( &cacrl, 0, sizeof(x509_crl) );
#endif
    pk_init( &pkey );

    if( argc == 0 )
    {
    usage:
        polarssl_printf( USAGE );
        ret = 2;
        goto exit;
    }

    opt.mode                = DFL_MODE;
    opt.filename            = DFL_FILENAME;
    opt.ca_file             = DFL_CA_FILE;
    opt.crl_file            = DFL_CRL_FILE;
    opt.ca_path             = DFL_CA_PATH;
    opt.server_name         = DFL_SERVER_NAME;
    opt.server_port         = DFL_SERVER_PORT;
    opt.debug_level         = DFL_DEBUG_LEVEL;
    opt.permissive          = DFL_PERMISSIVE;

    for( i = 1; i < argc; i++ )
    {
        p = argv[i];
        if( ( q = strchr( p, '=' ) ) == NULL )
            goto usage;
        *q++ = '\0';

        for( j = 0; p + j < q; j++ )
        {
            if( argv[i][j] >= 'A' && argv[i][j] <= 'Z' )
                argv[i][j] |= 0x20;
        }

        if( strcmp( p, "mode" ) == 0 )
        {
            if( strcmp( q, "file" ) == 0 )
                opt.mode = MODE_FILE;
            else if( strcmp( q, "ssl" ) == 0 )
                opt.mode = MODE_SSL;
            else
                goto usage;
        }
        else if( strcmp( p, "filename" ) == 0 )
            opt.filename = q;
        else if( strcmp( p, "ca_file" ) == 0 )
            opt.ca_file = q;
        else if( strcmp( p, "crl_file" ) == 0 )
            opt.crl_file = q;
        else if( strcmp( p, "ca_path" ) == 0 )
            opt.ca_path = q;
        else if( strcmp( p, "server_name" ) == 0 )
            opt.server_name = q;
        else if( strcmp( p, "server_port" ) == 0 )
        {
            opt.server_port = atoi( q );
            if( opt.server_port < 1 || opt.server_port > 65535 )
                goto usage;
        }
        else if( strcmp( p, "debug_level" ) == 0 )
        {
            opt.debug_level = atoi( q );
            if( opt.debug_level < 0 || opt.debug_level > 65535 )
                goto usage;
        }
        else if( strcmp( p, "permissive" ) == 0 )
        {
            opt.permissive = atoi( q );
            if( opt.permissive < 0 || opt.permissive > 1 )
                goto usage;
        }
        else
            goto usage;
    }

    /*
     * 1.1. Load the trusted CA
     */
    polarssl_printf( "  . Loading the CA root certificate ..." );
    fflush( stdout );

    if( strlen( opt.ca_path ) )
    {
        ret = x509_crt_parse_path( &cacert, opt.ca_path );
        verify = 1;
    }
    else if( strlen( opt.ca_file ) )
    {
        ret = x509_crt_parse_file( &cacert, opt.ca_file );
        verify = 1;
    }

    if( ret < 0 )
    {
        polarssl_printf( " failed\n  !  x509_crt_parse returned -0x%x\n\n", -ret );
        goto exit;
    }

    polarssl_printf( " ok (%d skipped)\n", ret );

#if defined(POLARSSL_X509_CRL_PARSE_C)
    if( strlen( opt.crl_file ) )
    {
        if( ( ret = x509_crl_parse_file( &cacrl, opt.crl_file ) ) != 0 )
        {
            polarssl_printf( " failed\n  !  x509_crl_parse returned -0x%x\n\n", -ret );
            goto exit;
        }

        verify = 1;
    }
#endif

    if( opt.mode == MODE_FILE )
    {
        x509_crt crt;
        x509_crt *cur = &crt;
        x509_crt_init( &crt );

        /*
         * 1.1. Load the certificate(s)
         */
        polarssl_printf( "\n  . Loading the certificate(s) ..." );
        fflush( stdout );

        ret = x509_crt_parse_file( &crt, opt.filename );

        if( ret < 0 )
        {
            polarssl_printf( " failed\n  !  x509_crt_parse_file returned %d\n\n", ret );
            x509_crt_free( &crt );
            goto exit;
        }

        if( opt.permissive == 0 && ret > 0 )
        {
            polarssl_printf( " failed\n  !  x509_crt_parse failed to parse %d certificates\n\n", ret );
            x509_crt_free( &crt );
            goto exit;
        }

        polarssl_printf( " ok\n" );

        /*
         * 1.2 Print the certificate(s)
         */
        while( cur != NULL )
        {
            polarssl_printf( "  . Peer certificate information    ...\n" );
            ret = x509_crt_info( (char *) buf, sizeof( buf ) - 1, "      ",
                                 cur );
            if( ret == -1 )
            {
                polarssl_printf( " failed\n  !  x509_crt_info returned %d\n\n", ret );
                x509_crt_free( &crt );
                goto exit;
            }

            polarssl_printf( "%s\n", buf );

            cur = cur->next;
        }

        /*
         * 1.3 Verify the certificate
         */
        if( verify )
        {
            polarssl_printf( "  . Verifying X.509 certificate..." );

            if( ( ret = x509_crt_verify( &crt, &cacert, &cacrl, NULL, &flags,
                                         my_verify, NULL ) ) != 0 )
            {
                polarssl_printf( " failed\n" );

                if( ( ret & BADCERT_EXPIRED ) != 0 )
                    polarssl_printf( "  ! server certificate has expired\n" );

                if( ( ret & BADCERT_REVOKED ) != 0 )
                    polarssl_printf( "  ! server certificate has been revoked\n" );

                if( ( ret & BADCERT_CN_MISMATCH ) != 0 )
                    polarssl_printf( "  ! CN mismatch (expected CN=%s)\n", opt.server_name );

                if( ( ret & BADCERT_NOT_TRUSTED ) != 0 )
                    polarssl_printf( "  ! self-signed or not signed by a trusted CA\n" );

                polarssl_printf( "\n" );
            }
            else
                polarssl_printf( " ok\n" );
        }

        x509_crt_free( &crt );
    }
    else if( opt.mode == MODE_SSL )
    {
        /*
         * 1. Initialize the RNG and the session data
         */
        polarssl_printf( "\n  . Seeding the random number generator..." );
        fflush( stdout );

        entropy_init( &entropy );
        if( ( ret = ctr_drbg_init( &ctr_drbg, entropy_func, &entropy,
                                   (const unsigned char *) pers,
                                   strlen( pers ) ) ) != 0 )
        {
            polarssl_printf( " failed\n  ! ctr_drbg_init returned %d\n", ret );
            goto exit;
        }

        polarssl_printf( " ok\n" );

        /*
         * 2. Start the connection
         */
        polarssl_printf( "  . SSL connection to tcp/%s/%-4d...", opt.server_name,
                                                        opt.server_port );
        fflush( stdout );

        if( ( ret = net_connect( &server_fd, opt.server_name,
                                             opt.server_port ) ) != 0 )
        {
            polarssl_printf( " failed\n  ! net_connect returned %d\n\n", ret );
            goto exit;
        }

        /*
         * 3. Setup stuff
         */
        if( ( ret = ssl_init( &ssl ) ) != 0 )
        {
            polarssl_printf( " failed\n  ! ssl_init returned %d\n\n", ret );
            goto exit;
        }

        ssl_set_endpoint( &ssl, SSL_IS_CLIENT );
        if( verify )
        {
            ssl_set_authmode( &ssl, SSL_VERIFY_REQUIRED );
            ssl_set_ca_chain( &ssl, &cacert, NULL, opt.server_name );
            ssl_set_verify( &ssl, my_verify, NULL );
        }
        else
            ssl_set_authmode( &ssl, SSL_VERIFY_NONE );

        ssl_set_rng( &ssl, ctr_drbg_random, &ctr_drbg );
        ssl_set_dbg( &ssl, my_debug, stdout );
        ssl_set_bio( &ssl, net_recv, &server_fd,
                net_send, &server_fd );

        if( ( ret = ssl_set_own_cert( &ssl, &clicert, &pkey ) ) != 0 )
        {
            polarssl_printf( " failed\n  ! ssl_set_own_cert returned %d\n\n", ret );
            goto exit;
        }

#if defined(POLARSSL_SSL_SERVER_NAME_INDICATION)
        if( ( ret = ssl_set_hostname( &ssl, opt.server_name ) ) != 0 )
        {
            polarssl_printf( " failed\n  ! ssl_set_hostname returned %d\n\n", ret );
            goto exit;
        }
#endif

        /*
         * 4. Handshake
         */
        while( ( ret = ssl_handshake( &ssl ) ) != 0 )
        {
            if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE )
            {
                polarssl_printf( " failed\n  ! ssl_handshake returned %d\n\n", ret );
                ssl_free( &ssl );
                goto exit;
            }
        }

        polarssl_printf( " ok\n" );

        /*
         * 5. Print the certificate
         */
        polarssl_printf( "  . Peer certificate information    ...\n" );
        ret = x509_crt_info( (char *) buf, sizeof( buf ) - 1, "      ",
                             ssl.session->peer_cert );
        if( ret == -1 )
        {
            polarssl_printf( " failed\n  !  x509_crt_info returned %d\n\n", ret );
            ssl_free( &ssl );
            goto exit;
        }

        polarssl_printf( "%s\n", buf );

        ssl_close_notify( &ssl );
        ssl_free( &ssl );
    }
    else
        goto usage;

exit:

    if( server_fd )
        net_close( server_fd );
    x509_crt_free( &cacert );
    x509_crt_free( &clicert );
#if defined(POLARSSL_X509_CRL_PARSE_C)
    x509_crl_free( &cacrl );
#endif
    pk_free( &pkey );
    ctr_drbg_free( &ctr_drbg );
    entropy_free( &entropy );

#if defined(_WIN32)
    polarssl_printf( "  + Press Enter to exit this program.\n" );
    fflush( stdout ); getchar();
#endif

    if( ret < 0 )
        ret = 1;

    return( ret );
}
char *test_SSL_verify_cert() 
{

    x509_crt crt;
    memset( &crt, 0, sizeof crt );

    x509_crt ca_crt;
    memset( &ca_crt, 0, sizeof ca_crt );

    x509_crl crl;
    memset( &crl, 0, sizeof crl );

    int ret = 0;

    ret =x509_crt_parse_file( &crt, "tests/ca/certs/m2-cert.pem" );

    mu_assert(ret == 0, "failed to parse cert m2-cert.pem");

    ret =x509_crt_parse_file( &ca_crt, "tests/ca/none.pem" );

    mu_assert(ret != 0, "failed to fail on non-existent pem none.pem");

    ret =x509_crt_parse_file( &ca_crt, "tests/ca/cacert.pem" );

    mu_assert(ret == 0, "failed to parse cert cacert.pem");

    ret =x509_crl_parse_file( &crl, "tests/ca/crl.pem" );

    mu_assert(ret == 0, "failed to parse cert crl.pem");

    /*
     * Validate the cert.  Since these certs are only valid within a certain time period, this test
     * will fail when the current time is outside this period.  To avoid false failures (eg. when
     * building/testing this version of the software in the distant future), adjust the expected
     * test outcome accordingly.  However, log the failure to stderr so that the maintainer can
     * detect the expiry of the cert, and generate/commit a new one from time to time.
     */
    int flags = 0;
    ret =x509_crt_verify( &crt, &ca_crt, NULL, NULL, &flags, NULL, NULL);
    if ( ret ) {
	char buf[1024];
	buf[0] = 0;
	polarssl_strerror( ret, buf, sizeof buf );
	fprintf( stderr, "*** x509_crt_verify of m2-cert.pem: %d: %s\n", ret, buf );
    }
    int valid_from = x509_time_expired( &crt.valid_from );
    int valid_to   = x509_time_expired( &crt.valid_to );

    int expected = 0;
    if ( valid_from == BADCERT_EXPIRED && valid_to == BADCERT_EXPIRED ) {
	/*
	 * This cert hasn't yet become active, or has already expired; expect
	 * X509 cert failure (-0x2700)
	 */
	fprintf( stderr, "*** x509_crt_verify WILL FAIL because current data is outside: valid_from '%d/%d/%d %d:%d:%d': %d, valid_to '%d/%d/%d %d:%d:%d': %d\n",
	       crt.valid_from.year, crt.valid_from.mon, crt.valid_from.day, crt.valid_from.hour, crt.valid_from.min, crt.valid_from.sec, valid_from,
	       crt.valid_to  .year, crt.valid_to  .mon, crt.valid_to  .day, crt.valid_to  .hour, crt.valid_to  .min, crt.valid_to  .sec, valid_to );
	fprintf( stderr, "*** If this is the currently supported version, generate and commit a new tests/ca/m2-cert.pem with valid dates\n" );
	expected = POLARSSL_ERR_X509_CERT_VERIFY_FAILED;
    }
    mu_assert(ret == expected, "failed to verify cert m2-cert.pem");

    x509_crt_free( &crt );
    x509_crt_free( &ca_crt );
    x509_crl_free( &crl );

    return NULL;
}
int main( int argc, char *argv[] )
{
    int ret, i;
    x509_crt cacert;
    x509_crl crl;
    char buf[10240];

    ((void) argc);
    ((void) argv);

    x509_crt_init( &cacert );
    x509_crl_init( &crl );

    /*
     * 1.1. Load the trusted CA
     */
    printf( "\n  . Loading the CA root certificate ..." );
    fflush( stdout );

    /*
     * Alternatively, you may load the CA certificates from a .pem or
     * .crt file by calling x509_crt_parse_file( &cacert, "myca.crt" ).
     */
    ret = x509_crt_parse_file( &cacert, "ssl/test-ca/test-ca.crt" );
    if( ret != 0 )
    {
        printf( " failed\n  !  x509_crt_parse_file returned %d\n\n", ret );
        goto exit;
    }

    printf( " ok\n" );

    x509_crt_info( buf, 1024, "CRT: ", &cacert );
    printf("%s\n", buf );

    /*
     * 1.2. Load the CRL
     */
    printf( "  . Loading the CRL ..." );
    fflush( stdout );

    ret = x509_crl_parse_file( &crl, "ssl/test-ca/crl.pem" );
    if( ret != 0 )
    {
        printf( " failed\n  !  x509_crl_parse_file returned %d\n\n", ret );
        goto exit;
    }

    printf( " ok\n" );

    x509_crl_info( buf, 1024, "CRL: ", &crl );
    printf("%s\n", buf );

    for( i = 0; i < MAX_CLIENT_CERTS; i++ )
    {
        /*
         * 1.3. Load own certificate
         */
        char    name[512];
        int flags;
        x509_crt clicert;
        pk_context pk;

        x509_crt_init( &clicert );
        pk_init( &pk );

        snprintf(name, 512, "ssl/test-ca/%s", client_certificates[i]);

        printf( "  . Loading the client certificate %s...", name );
        fflush( stdout );

        ret = x509_crt_parse_file( &clicert, name );
        if( ret != 0 )
        {
            printf( " failed\n  !  x509_crt_parse_file returned %d\n\n", ret );
            goto exit;
        }

        printf( " ok\n" );

        /*
         * 1.4. Verify certificate validity with CA certificate
         */
        printf( "  . Verify the client certificate with CA certificate..." );
        fflush( stdout );

        ret = x509_crt_verify( &clicert, &cacert, &crl, NULL, &flags, NULL,
                               NULL );
        if( ret != 0 )
        {
            if( ret == POLARSSL_ERR_X509_CERT_VERIFY_FAILED )
            {
                if( flags & BADCERT_CN_MISMATCH )
                    printf( " CN_MISMATCH " );
                if( flags & BADCERT_EXPIRED )
                    printf( " EXPIRED " );
                if( flags & BADCERT_REVOKED )
                    printf( " REVOKED " );
                if( flags & BADCERT_NOT_TRUSTED )
                    printf( " NOT_TRUSTED " );
                if( flags & BADCRL_NOT_TRUSTED )
                    printf( " CRL_NOT_TRUSTED " );
                if( flags & BADCRL_EXPIRED )
                    printf( " CRL_EXPIRED " );
            } else {
                printf( " failed\n  !  x509_crt_verify returned %d\n\n", ret );
                goto exit;
            }
        }

        printf( " ok\n" );

        /*
         * 1.5. Load own private key
         */
        snprintf(name, 512, "ssl/test-ca/%s", client_private_keys[i]);

        printf( "  . Loading the client private key %s...", name );
        fflush( stdout );

        ret = pk_parse_keyfile( &pk, name, NULL );
        if( ret != 0 )
        {
            printf( " failed\n  !  pk_parse_keyfile returned %d\n\n", ret );
            goto exit;
        }

        printf( " ok\n" );

        /*
         * 1.6. Verify certificate validity with private key
         */
        printf( "  . Verify the client certificate with private key..." );
        fflush( stdout );


        /* EC NOT IMPLEMENTED YET */
        if( ! pk_can_do( &clicert.pk, POLARSSL_PK_RSA ) )
        {
            printf( " failed\n  !  certificate's key is not RSA\n\n" );
            ret = POLARSSL_ERR_X509_FEATURE_UNAVAILABLE;
            goto exit;
        }

        ret = mpi_cmp_mpi(&pk_rsa( pk )->N, &pk_rsa( clicert.pk )->N);
        if( ret != 0 )
        {
            printf( " failed\n  !  mpi_cmp_mpi for N returned %d\n\n", ret );
            goto exit;
        }

        ret = mpi_cmp_mpi(&pk_rsa( pk )->E, &pk_rsa( clicert.pk )->E);
        if( ret != 0 )
        {
            printf( " failed\n  !  mpi_cmp_mpi for E returned %d\n\n", ret );
            goto exit;
        }

        ret = rsa_check_privkey( pk_rsa( pk ) );
        if( ret != 0 )
        {
            printf( " failed\n  !  rsa_check_privkey returned %d\n\n", ret );
            goto exit;
        }

        printf( " ok\n" );

        x509_crt_free( &clicert );
        pk_free( &pk );
    }

exit:
    x509_crt_free( &cacert );
    x509_crl_free( &crl );

#if defined(_WIN32)
    printf( "  + Press Enter to exit this program.\n" );
    fflush( stdout ); getchar();
#endif

    return( ret );
}
Beispiel #13
0
/*
 * Parse one or more CRLs and add them to the chained list
 */
int x509_crl_parse( x509_crl *chain, const unsigned char *buf, size_t buflen )
{
    int ret;
    size_t len;
    unsigned char *p, *end;
    x509_crl *crl;
#if defined(POLARSSL_PEM_PARSE_C)
    size_t use_len;
    pem_context pem;
#endif

    crl = chain;

    /*
     * Check for valid input
     */
    if( crl == NULL || buf == NULL )
        return( POLARSSL_ERR_X509_BAD_INPUT_DATA );

    while( crl->version != 0 && crl->next != NULL )
        crl = crl->next;

    /*
     * Add new CRL on the end of the chain if needed.
     */
    if ( crl->version != 0 && crl->next == NULL)
    {
        crl->next = (x509_crl *) polarssl_malloc( sizeof( x509_crl ) );

        if( crl->next == NULL )
        {
            x509_crl_free( crl );
            return( POLARSSL_ERR_X509_MALLOC_FAILED );
        }

        crl = crl->next;
        x509_crl_init( crl );
    }

#if defined(POLARSSL_PEM_PARSE_C)
    pem_init( &pem );
    ret = pem_read_buffer( &pem,
                           "-----BEGIN X509 CRL-----",
                           "-----END X509 CRL-----",
                           buf, NULL, 0, &use_len );

    if( ret == 0 )
    {
        /*
         * Was PEM encoded
         */
        buflen -= use_len;
        buf += use_len;

        /*
         * Steal PEM buffer
         */
        p = pem.buf;
        pem.buf = NULL;
        len = pem.buflen;
        pem_free( &pem );
    }
    else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
    {
        pem_free( &pem );
        return( ret );
    }
    else
#endif
    {
        /*
         * nope, copy the raw DER data
         */
        p = (unsigned char *) polarssl_malloc( len = buflen );

        if( p == NULL )
            return( POLARSSL_ERR_X509_MALLOC_FAILED );

        memcpy( p, buf, buflen );

        buflen = 0;
    }

    crl->raw.p = p;
    crl->raw.len = len;
    end = p + len;

    /*
     * CertificateList  ::=  SEQUENCE  {
     *      tbsCertList          TBSCertList,
     *      signatureAlgorithm   AlgorithmIdentifier,
     *      signatureValue       BIT STRING  }
     */
    if( ( ret = asn1_get_tag( &p, end, &len,
            ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
    {
        x509_crl_free( crl );
        return( POLARSSL_ERR_X509_INVALID_FORMAT );
    }

    if( len != (size_t) ( end - p ) )
    {
        x509_crl_free( crl );
        return( POLARSSL_ERR_X509_INVALID_FORMAT +
                POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
    }

    /*
     * TBSCertList  ::=  SEQUENCE  {
     */
    crl->tbs.p = p;

    if( ( ret = asn1_get_tag( &p, end, &len,
            ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
    {
        x509_crl_free( crl );
        return( POLARSSL_ERR_X509_INVALID_FORMAT + ret );
    }

    end = p + len;
    crl->tbs.len = end - crl->tbs.p;

    /*
     * Version  ::=  INTEGER  OPTIONAL {  v1(0), v2(1)  }
     *               -- if present, MUST be v2
     *
     * signature            AlgorithmIdentifier
     */
    if( ( ret = x509_crl_get_version( &p, end, &crl->version ) ) != 0 ||
        ( ret = x509_get_alg_null( &p, end, &crl->sig_oid1   ) ) != 0 )
    {
        x509_crl_free( crl );
        return( ret );
    }

    crl->version++;

    if( crl->version > 2 )
    {
        x509_crl_free( crl );
        return( POLARSSL_ERR_X509_UNKNOWN_VERSION );
    }

    if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &crl->sig_md,
                                  &crl->sig_pk ) ) != 0 )
    {
        x509_crl_free( crl );
        return( POLARSSL_ERR_X509_UNKNOWN_SIG_ALG );
    }

    /*
     * issuer               Name
     */
    crl->issuer_raw.p = p;

    if( ( ret = asn1_get_tag( &p, end, &len,
            ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
    {
        x509_crl_free( crl );
        return( POLARSSL_ERR_X509_INVALID_FORMAT + ret );
    }

    if( ( ret = x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
    {
        x509_crl_free( crl );
        return( ret );
    }

    crl->issuer_raw.len = p - crl->issuer_raw.p;

    /*
     * thisUpdate          Time
     * nextUpdate          Time OPTIONAL
     */
    if( ( ret = x509_get_time( &p, end, &crl->this_update ) ) != 0 )
    {
        x509_crl_free( crl );
        return( ret );
    }

    if( ( ret = x509_get_time( &p, end, &crl->next_update ) ) != 0 )
    {
        if ( ret != ( POLARSSL_ERR_X509_INVALID_DATE +
                        POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) &&
             ret != ( POLARSSL_ERR_X509_INVALID_DATE +
                        POLARSSL_ERR_ASN1_OUT_OF_DATA ) )
        {
            x509_crl_free( crl );
            return( ret );
        }
    }

    /*
     * revokedCertificates    SEQUENCE OF SEQUENCE   {
     *      userCertificate        CertificateSerialNumber,
     *      revocationDate         Time,
     *      crlEntryExtensions     Extensions OPTIONAL
     *                                   -- if present, MUST be v2
     *                        } OPTIONAL
     */
    if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
    {
        x509_crl_free( crl );
        return( ret );
    }

    /*
     * crlExtensions          EXPLICIT Extensions OPTIONAL
     *                              -- if present, MUST be v2
     */
    if( crl->version == 2 )
    {
        ret = x509_get_crl_ext( &p, end, &crl->crl_ext );

        if( ret != 0 )
        {
            x509_crl_free( crl );
            return( ret );
        }
    }

    if( p != end )
    {
        x509_crl_free( crl );
        return( POLARSSL_ERR_X509_INVALID_FORMAT +
                POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
    }

    end = crl->raw.p + crl->raw.len;

    /*
     *  signatureAlgorithm   AlgorithmIdentifier,
     *  signatureValue       BIT STRING
     */
    if( ( ret = x509_get_alg_null( &p, end, &crl->sig_oid2 ) ) != 0 )
    {
        x509_crl_free( crl );
        return( ret );
    }

    if( crl->sig_oid1.len != crl->sig_oid2.len ||
        memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 )
    {
        x509_crl_free( crl );
        return( POLARSSL_ERR_X509_SIG_MISMATCH );
    }

    if( ( ret = x509_get_sig( &p, end, &crl->sig ) ) != 0 )
    {
        x509_crl_free( crl );
        return( ret );
    }

    if( p != end )
    {
        x509_crl_free( crl );
        return( POLARSSL_ERR_X509_INVALID_FORMAT +
                POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
    }

    if( buflen > 0 )
    {
        crl->next = (x509_crl *) polarssl_malloc( sizeof( x509_crl ) );

        if( crl->next == NULL )
        {
            x509_crl_free( crl );
            return( POLARSSL_ERR_X509_MALLOC_FAILED );
        }

        crl = crl->next;
        x509_crl_init( crl );

        return( x509_crl_parse( crl, buf, buflen ) );
    }

    return( 0 );
}