Beispiel #1
0
result_t PKey::verify(Buffer_base *sign, Buffer_base *data, bool &retVal,
                      exlib::AsyncEvent *ac)
{
    if (switchToAsync(ac))
        return CHECK_ERROR(CALL_E_NOSYNC);

    int ret;
    std::string str;
    std::string strsign;

    data->toString(str);
    sign->toString(strsign);

    ret = pk_verify(&m_key, POLARSSL_MD_NONE,
                    (const unsigned char *)str.c_str(), str.length(),
                    (const unsigned char *)strsign.c_str(), strsign.length());
    if (ret == POLARSSL_ERR_ECP_VERIFY_FAILED ||
            ret == POLARSSL_ERR_RSA_VERIFY_FAILED)
    {
        retVal = false;
        return 0;
    }

    if (ret != 0)
        return CHECK_ERROR(_ssl::setError(ret));

    retVal = true;

    return 0;
}
Beispiel #2
0
/*
 * Verify a signature with options
 */
int pk_verify_ext( pk_type_t type, const void *options,
                   pk_context *ctx, md_type_t md_alg,
                   const unsigned char *hash, size_t hash_len,
                   const unsigned char *sig, size_t sig_len )
{
    if( ctx == NULL || ctx->pk_info == NULL )
        return( POLARSSL_ERR_PK_BAD_INPUT_DATA );

    if( ! pk_can_do( ctx, type ) )
        return( POLARSSL_ERR_PK_TYPE_MISMATCH );

    if( type == POLARSSL_PK_RSASSA_PSS )
    {
#if defined(POLARSSL_RSA_C) && defined(POLARSSL_PKCS1_V21)
        int ret;
        const pk_rsassa_pss_options *pss_opts;

        if( options == NULL )
            return( POLARSSL_ERR_PK_BAD_INPUT_DATA );

        pss_opts = (const pk_rsassa_pss_options *) options;

        if( sig_len < pk_get_len( ctx ) )
            return( POLARSSL_ERR_RSA_VERIFY_FAILED );

        ret = rsa_rsassa_pss_verify_ext( pk_rsa( *ctx ),
                NULL, NULL, RSA_PUBLIC,
                md_alg, hash_len, hash,
                pss_opts->mgf1_hash_id,
                pss_opts->expected_salt_len,
                sig );
        if( ret != 0 )
            return( ret );

        if( sig_len > pk_get_len( ctx ) )
            return( POLARSSL_ERR_PK_SIG_LEN_MISMATCH );

        return( 0 );
#else
        return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE );
#endif
    }

    /* General case: no options */
    if( options != NULL )
        return( POLARSSL_ERR_PK_BAD_INPUT_DATA );

    return( pk_verify( ctx, md_alg, hash, hash_len, sig, sig_len ) );
}
Beispiel #3
0
int main( int argc, char *argv[] )
{
    FILE *f;
    int ret = 1;
    size_t i;
    pk_context pk;
    unsigned char hash[20];
    unsigned char buf[POLARSSL_MPI_MAX_SIZE];
    char filename[512];

    pk_init( &pk );

    if( argc != 3 )
    {
        printf( "usage: pk_verify <key_file> <filename>\n" );

#if defined(_WIN32)
        printf( "\n" );
#endif

        goto exit;
    }

    printf( "\n  . Reading public key from '%s'", argv[1] );
    fflush( stdout );

    if( ( ret = pk_parse_public_keyfile( &pk, argv[1] ) ) != 0 )
    {
        printf( " failed\n  ! pk_parse_public_keyfile returned -0x%04x\n", -ret );
        goto exit;
    }

    /*
     * Extract the signature from the text file
     */
    ret = 1;
    snprintf( filename, sizeof(filename), "%s.sig", argv[2] );

    if( ( f = fopen( filename, "rb" ) ) == NULL )
    {
        printf( "\n  ! Could not open %s\n\n", filename );
        goto exit;
    }


    i = fread( buf, 1, sizeof(buf), f );

    fclose( f );

    /*
     * Compute the SHA-1 hash of the input file and compare
     * it with the hash decrypted from the signature.
     */
    printf( "\n  . Verifying the SHA-1 signature" );
    fflush( stdout );

    if( ( ret = sha1_file( argv[2], hash ) ) != 0 )
    {
        printf( " failed\n  ! Could not open or read %s\n\n", argv[2] );
        goto exit;
    }

    if( ( ret = pk_verify( &pk, POLARSSL_MD_SHA1, hash, 0,
                           buf, i ) ) != 0 )
    {
        printf( " failed\n  ! pk_verify returned -0x%04x\n", -ret );
        goto exit;
    }

    printf( "\n  . OK (the decrypted SHA-1 hash matches)\n\n" );

    ret = 0;

exit:
    pk_free( &pk );

#if defined(POLARSSL_ERROR_C)
    polarssl_strerror( ret, (char *) buf, sizeof(buf) );
    printf( "  !  Last error was: %s\n", buf );
#endif

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

    return( ret );
}
Beispiel #4
0
static int x509_crt_verify_child(
                x509_crt *child, x509_crt *parent, x509_crt *trust_ca,
                x509_crl *ca_crl, int path_cnt, int *flags,
                int (*f_vrfy)(void *, x509_crt *, int, int *),
                void *p_vrfy )
{
    int ret;
    int parent_flags = 0;
    unsigned char hash[POLARSSL_MD_MAX_SIZE];
    x509_crt *grandparent;
    const md_info_t *md_info;

    if( x509_time_expired( &child->valid_to ) )
        *flags |= BADCERT_EXPIRED;

    md_info = md_info_from_type( child->sig_md );
    if( md_info == NULL )
    {
        /*
         * Cannot check 'unknown' hash
         */
        *flags |= BADCERT_NOT_TRUSTED;
    }
    else
    {
        md( md_info, child->tbs.p, child->tbs.len, hash );

        if( pk_can_do( &parent->pk, child->sig_pk ) == 0 ||
            pk_verify( &parent->pk, child->sig_md, hash, md_info->size,
                       child->sig.p, child->sig.len ) != 0 )
        {
            *flags |= BADCERT_NOT_TRUSTED;
        }
    }

#if defined(POLARSSL_X509_CRL_PARSE_C)
    /* Check trusted CA's CRL for the given crt */
    *flags |= x509_crt_verifycrl(child, parent, ca_crl);
#endif

    grandparent = parent->next;

    while( grandparent != NULL )
    {
        if( grandparent->version == 0 ||
            grandparent->ca_istrue == 0 ||
            parent->issuer_raw.len != grandparent->subject_raw.len ||
            memcmp( parent->issuer_raw.p, grandparent->subject_raw.p,
                    parent->issuer_raw.len ) != 0 )
        {
            grandparent = grandparent->next;
            continue;
        }
        break;
    }

    if( grandparent != NULL )
    {
        /*
         * Part of the chain
         */
        ret = x509_crt_verify_child( parent, grandparent, trust_ca, ca_crl, path_cnt + 1, &parent_flags, f_vrfy, p_vrfy );
        if( ret != 0 )
            return( ret );
    }
    else
    {
        ret = x509_crt_verify_top( parent, trust_ca, ca_crl, path_cnt + 1, &parent_flags, f_vrfy, p_vrfy );
        if( ret != 0 )
            return( ret );
    }

    /* child is verified to be a child of the parent, call verify callback */
    if( NULL != f_vrfy )
        if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 )
            return( ret );

    *flags |= parent_flags;

    return( 0 );
}
Beispiel #5
0
static int x509_crt_verify_top(
                x509_crt *child, x509_crt *trust_ca,
                x509_crl *ca_crl, int path_cnt, int *flags,
                int (*f_vrfy)(void *, x509_crt *, int, int *),
                void *p_vrfy )
{
    int ret;
    int ca_flags = 0, check_path_cnt = path_cnt + 1;
    unsigned char hash[POLARSSL_MD_MAX_SIZE];
    const md_info_t *md_info;

    if( x509_time_expired( &child->valid_to ) )
        *flags |= BADCERT_EXPIRED;

    /*
     * Child is the top of the chain. Check against the trust_ca list.
     */
    *flags |= BADCERT_NOT_TRUSTED;

    md_info = md_info_from_type( child->sig_md );
    if( md_info == NULL )
    {
        /*
         * Cannot check 'unknown', no need to try any CA
         */
        trust_ca = NULL;
    }
    else
        md( md_info, child->tbs.p, child->tbs.len, hash );

    while( trust_ca != NULL )
    {
        if( trust_ca->version == 0 ||
            child->issuer_raw.len != trust_ca->subject_raw.len ||
            memcmp( child->issuer_raw.p, trust_ca->subject_raw.p,
                    child->issuer_raw.len ) != 0 )
        {
            trust_ca = trust_ca->next;
            continue;
        }

        /*
         * Reduce path_len to check against if top of the chain is
         * the same as the trusted CA
         */
        if( child->subject_raw.len == trust_ca->subject_raw.len &&
            memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
                            child->issuer_raw.len ) == 0 )
        {
            check_path_cnt--;
        }

        if( trust_ca->max_pathlen > 0 &&
            trust_ca->max_pathlen < check_path_cnt )
        {
            trust_ca = trust_ca->next;
            continue;
        }

        if( pk_can_do( &trust_ca->pk, child->sig_pk ) == 0 ||
            pk_verify( &trust_ca->pk, child->sig_md, hash, md_info->size,
                       child->sig.p, child->sig.len ) != 0 )
        {
            trust_ca = trust_ca->next;
            continue;
        }

        /*
         * Top of chain is signed by a trusted CA
         */
        *flags &= ~BADCERT_NOT_TRUSTED;
        break;
    }

    /*
     * If top of chain is not the same as the trusted CA send a verify request
     * to the callback for any issues with validity and CRL presence for the
     * trusted CA certificate.
     */
    if( trust_ca != NULL &&
        ( child->subject_raw.len != trust_ca->subject_raw.len ||
          memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
                            child->issuer_raw.len ) != 0 ) )
    {
#if defined(POLARSSL_X509_CRL_PARSE_C)
        /* Check trusted CA's CRL for the chain's top crt */
        *flags |= x509_crt_verifycrl( child, trust_ca, ca_crl );
#else
        ((void) ca_crl);
#endif

        if( x509_time_expired( &trust_ca->valid_to ) )
            ca_flags |= BADCERT_EXPIRED;

        if( NULL != f_vrfy )
        {
            if( ( ret = f_vrfy( p_vrfy, trust_ca, path_cnt + 1, &ca_flags ) ) != 0 )
                return( ret );
        }
    }

    /* Call callback on top cert */
    if( NULL != f_vrfy )
    {
        if( ( ret = f_vrfy(p_vrfy, child, path_cnt, flags ) ) != 0 )
            return( ret );
    }

    *flags |= ca_flags;

    return( 0 );
}
Beispiel #6
0
/*
 * Check that the given certificate is valid according to the CRL.
 */
static int x509_crt_verifycrl( x509_crt *crt, x509_crt *ca,
                               x509_crl *crl_list)
{
    int flags = 0;
    unsigned char hash[POLARSSL_MD_MAX_SIZE];
    const md_info_t *md_info;

    if( ca == NULL )
        return( flags );

    /*
     * TODO: What happens if no CRL is present?
     * Suggestion: Revocation state should be unknown if no CRL is present.
     * For backwards compatibility this is not yet implemented.
     */

    while( crl_list != NULL )
    {
        if( crl_list->version == 0 ||
            crl_list->issuer_raw.len != ca->subject_raw.len ||
            memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
                    crl_list->issuer_raw.len ) != 0 )
        {
            crl_list = crl_list->next;
            continue;
        }

        /*
         * Check if CRL is correctly signed by the trusted CA
         */
        md_info = md_info_from_type( crl_list->sig_md );
        if( md_info == NULL )
        {
            /*
             * Cannot check 'unknown' hash
             */
            flags |= BADCRL_NOT_TRUSTED;
            break;
        }

        md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash );

        if( pk_can_do( &ca->pk, crl_list->sig_pk ) == 0 ||
            pk_verify( &ca->pk, crl_list->sig_md, hash, md_info->size,
                       crl_list->sig.p, crl_list->sig.len ) != 0 )
        {
            flags |= BADCRL_NOT_TRUSTED;
            break;
        }

        /*
         * Check for validity of CRL (Do not drop out)
         */
        if( x509_time_expired( &crl_list->next_update ) )
            flags |= BADCRL_EXPIRED;

        /*
         * Check if certificate is revoked
         */
        if( x509_crt_revoked(crt, crl_list) )
        {
            flags |= BADCERT_REVOKED;
            break;
        }

        crl_list = crl_list->next;
    }
    return flags;
}
void asymmetric_signature_verify(struct item *key, struct item *item,
                                 struct item *signature)
  /*@ requires [?f]world(?pub, ?key_clsfy) &*&
               item(item, ?i, pub) &*& item(key, ?k, pub) &*&
               item(signature, ?sig, pub) &*&
                 sig == asymmetric_signature_item(?principal1, ?count1,
                                                  ?pay1, ?ent) &*&
               k == public_key_item(?principal2, ?count2); @*/
  /*@ ensures  [f]world(pub, key_clsfy) &*&
               item(item, i, pub) &*& item(key, k, pub) &*&
               item(signature, sig, pub) &*&
               switch(pay1)
               {
                 case some(pay2):
                   return col || (principal1 == principal2 &&
                                  count1 == count2 && i == pay2);
                 case none:
                   return true == col;
               }; @*/
{
  debug_print("ASYM SIGNATURE CHECKING:\n");
  print_item(signature);
  check_is_asymmetric_signature(signature);

  {
    pk_context context;
    unsigned int olen;
    char* output;

    // Key
    //@ close pk_context(&context);
    //@ open [f]world(pub, key_clsfy);
    pk_init(&context);
    //@ close [f]world(pub, key_clsfy);
    set_public_key(&context, key);
    /*@ assert pk_context_with_key(&context, pk_public,
                                   ?principal3, ?count3, RSA_BIT_KEY_SIZE); @*/
    // Signature checking
    //@ open item(item, ?i_old, pub);
    //@ assert item->content |-> ?i_cont &*& item->size |-> ?i_size;
    //@ assert crypto_chars(secret, i_cont, i_size, ?i_cs);
    //@ assert [_]item_constraints(i, i_cs, pub);
    //@ open item(signature, _, pub);
    //@ assert signature->content |-> ?s_cont &*& signature->size |-> ?s_size;
    //@ assert crypto_chars(secret, s_cont, s_size, ?sig_cs);
    //@ open [_]item_constraints(sig, sig_cs, pub);
    //@ open ic_parts(sig)(?sig_tag, ?sig_cont);
    //@ take_append(TAG_LENGTH, sig_tag, sig_cont);
    //@ drop_append(TAG_LENGTH, sig_tag, sig_cont);
    //@ open [_]ic_cg(sig)(_, ?cg_sig);
    //@ assert cg_sig == cg_asym_signature(principal1, count1, ?cs_pay, ent);

    if (item->size > RSA_KEY_SIZE)
      abort_crypto_lib("Assymetric signature checking failed: incorrect sizes");

    //@ crypto_chars_limits(s_cont);
    //@ crypto_chars_split(s_cont, TAG_LENGTH);
    //@ assert crypto_chars(secret, s_cont, TAG_LENGTH, sig_tag);
    //@ assert crypto_chars(secret, s_cont + TAG_LENGTH, ?s, sig_cont);
    //@ assert s == s_size - TAG_LENGTH;
    //@ if (col) cg_sig = chars_for_cg_sur(sig_cont, tag_asym_signature);
    //@ if (col) crypto_chars_to_chars(s_cont + TAG_LENGTH, s);
    //@ if (col) public_chars_extract(s_cont + TAG_LENGTH, cg_sig);
    //@ if (col) chars_to_secret_crypto_chars(s_cont + TAG_LENGTH, s);
    //@ close cryptogram(s_cont + TAG_LENGTH, s, sig_cont, cg_sig);
    if(pk_verify(&context, POLARSSL_MD_NONE, item->content,
                 (unsigned int) item->size,
                 signature->content + TAG_LENGTH,
                 (unsigned int) (signature->size - TAG_LENGTH)) != 0)
      abort_crypto_lib("Signing check failed: signature"
                       "was not created with the provided key");
    //@ pk_release_context_with_key(&context);
    pk_free(&context);
    //@ open pk_context(&context);
    //@ open cryptogram(s_cont + TAG_LENGTH, s, sig_cont, cg_sig);
    //@ crypto_chars_join(s_cont);
    //@ close item(signature, sig, pub);

    /*@ if (!col)
        {
          assert principal2 == principal3;
          assert count2 == count3;
          assert cs_pay == i_cs;
          open [_]item_constraints(i, cs_pay, pub);
          switch(pay1)
          {
            case some(pay2):
              assert [_]item_constraints(pay2, cs_pay, pub);
              item_constraints_injective(i, pay2, cs_pay);
            case none:
              open [_]ill_formed_item_chars(sig)(cs_pay);
              assert false;
          }
        }
    @*/
    //@ close item(item, i, pub);
  }
}