⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 x509read_c.htm

📁 阅读x.509文件的代码
💻 HTM
📖 第 1 页 / 共 4 页
字号:
    }

    if( ( ret = rsa_check_pubkey( &crt->rsa ) ) != 0 )
    {
        x509_free_cert( crt );
        return( ret );
    }

    crt->rsa.len = ( mpi_msb( &crt->rsa.N ) + 7 ) >> 3;

    /*
     *  issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
     *                       -- If present, version shall be v2 or v3
     *  subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
     *                       -- If present, version shall be v2 or v3
     *  extensions      [3]  EXPLICIT Extensions OPTIONAL
     *                       -- If present, version shall be v3
     */
    if( crt->version == 2 || crt->version == 3 )
    {
        ret = x509_get_uid( &p, end, &crt->issuer_id,  1 );
        if( ret != 0 )
        {
            x509_free_cert( crt );
            return( ret );
        }
    }

    if( crt->version == 2 || crt->version == 3 )
    {
        ret = x509_get_uid( &p, end, &crt->subject_id,  2 );
        if( ret != 0 )
        {
            x509_free_cert( crt );
            return( ret );
        }
    }

    if( crt->version == 3 )
    {
        ret = x509_get_ext( &p, end, &crt->v3_ext,
                            &crt->ca_istrue, &crt->max_pathlen );
        if( ret != 0 )
        {
            x509_free_cert( crt );
            return( ret );
        }
    }

    if( p != end )
    {
        x509_free_cert( crt );
        return( ERR_X509_CERT_INVALID_FORMAT |
                ERR_ASN1_LENGTH_MISMATCH );
    }

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

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

    if( memcmp( crt->sig_oid1.p, crt->sig_oid2.p, 9 ) != 0 )
    {
        x509_free_cert( crt );
        return( ERR_X509_CERT_SIG_MISMATCH );
    }

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

    if( p != end )
    {
        x509_free_cert( crt );
        return( ERR_X509_CERT_INVALID_FORMAT |
                ERR_ASN1_LENGTH_MISMATCH );
    }

    crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );

    if( crt->next == NULL )
    {
        x509_free_cert( crt );
        return( 1 );
    }

    crt = crt->next;
    memset( crt, 0, sizeof( x509_cert ) );

    if( buflen > 0 )
        return( x509_add_certs( crt, buf, buflen ) );

    return( 0 );
}

/*
 * Load one or more certificates and add them to the chain
 */
int x509_read_crtfile( x509_cert *chain, char *path )
{
    int ret;
    FILE *f;
    size_t n;
    unsigned char *buf;

    if( ( f = fopen( path, "rb" ) ) == NULL )
        return( 1 );

    fseek( f, 0, SEEK_END );
    n = (size_t) ftell( f );
    fseek( f, 0, SEEK_SET );

    if( ( buf = (unsigned char *) malloc( n + 1 ) ) == NULL )
        return( 1 );

    if( fread( buf, 1, n, f ) != n )
    {
        fclose( f );
        free( buf );
        return( 1 );
    }

    buf[n] = '\0';

    ret = x509_add_certs( chain, buf, (int) n );

    memset( buf, 0, n + 1 );
    free( buf );
    fclose( f );

    return( ret );
}

#if !defined(NO_DES)
/*
 * Read a 16-byte hex string and convert it to binary
 */
static int x509_des3_getiv( unsigned char *s, unsigned char iv[8] )
{
    int i, j;

    memset( iv, 0, 8 );

    for( i = 0; i < 16; i++, s++ )
    {
        if( *s >= '0' && *s <= '9' ) j = *s - '0'; else
        if( *s >= 'A' && *s <= 'F' ) j = *s - '7'; else
        if( *s >= 'a' && *s <= 'f' ) j = *s - 'W'; else
            return( ERR_X509_KEY_INVALID_ENC_IV );

        if( (i & 1) != 0 )
            iv[i >> 1] |= j;
        else
            iv[i >> 1] |= j << 4;
    }

    return( 0 );
}

/*
 * Decrypt with 3DES-CBC, using PBKDF1 for key derivation
 */
static void x509_des3_decrypt( unsigned char des3_iv[8],
                               unsigned char *buf, int buflen,
                               unsigned char *pwd, int pwdlen )
{
    md5_context md5_ctx;
    des3_context des3_ctx;
    unsigned char md5sum[16];
    unsigned char des3_key[24];

    /*
     * 3DES key[ 0..15] = MD5(pwd || IV)
     *      key[16..23] = MD5(pwd || IV || 3DES key[ 0..15])
     */
    md5_starts( &md5_ctx );
    md5_update( &md5_ctx, pwd, pwdlen );
    md5_update( &md5_ctx, des3_iv,  8 );
    md5_finish( &md5_ctx, md5sum );
    memcpy( des3_key, md5sum, 16 );

    md5_starts( &md5_ctx );
    md5_update( &md5_ctx, md5sum,  16 );
    md5_update( &md5_ctx, pwd, pwdlen );
    md5_update( &md5_ctx, des3_iv,  8 );
    md5_finish( &md5_ctx, md5sum );
    memcpy( des3_key + 16, md5sum, 8 );

    des3_set_3keys( &des3_ctx, des3_key );
    des3_cbc_decrypt( &des3_ctx, des3_iv, buf, buf, buflen );

    memset( & md5_ctx, 0, sizeof(  md5_ctx ) );
    memset( &des3_ctx, 0, sizeof( des3_ctx ) );
    memset( md5sum, 0, 16 );
    memset( des3_key, 0, 24 );
}
#endif

/*
 * Parse a private RSA key
 */
int x509_parse_key( rsa_context *rsa, unsigned char *buf, int buflen,
                                      unsigned char *pwd, int pwdlen )
{
    int ret, len, enc;
    unsigned char *s1, *s2;
    unsigned char *p, *end;
    unsigned char des3_iv[8];

    s1 = (unsigned char *) strstr( (char *) buf,
        "-----BEGIN RSA PRIVATE KEY-----" );

    if( s1 != NULL )
    {
        s2 = (unsigned char *) strstr( (char *) buf,
            "-----END RSA PRIVATE KEY-----" );

        if( s2 == NULL || s2 <= s1 )
            return( ERR_X509_KEY_INVALID_PEM );

        s1 += 31;
        if( *s1 == '\r' ) s1++;
        if( *s1 == '\n' ) s1++;
            else return( ERR_X509_KEY_INVALID_PEM );

        enc = 0;

        if( memcmp( s1, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 )
        {
#if !defined(NO_DES)
            enc++;

            s1 += 22;
            if( *s1 == '\r' ) s1++;
            if( *s1 == '\n' ) s1++;
                else return( ERR_X509_KEY_INVALID_PEM );

            if( memcmp( s1, "DEK-Info: DES-EDE3-CBC,", 23 ) != 0 )
                return( ERR_X509_KEY_UNKNOWN_ENC_ALG );

            s1 += 23;
            if( x509_des3_getiv( s1, des3_iv ) != 0 )
                return( ERR_X509_KEY_INVALID_ENC_IV );

            s1 += 16;
            if( *s1 == '\r' ) s1++;
            if( *s1 == '\n' ) s1++;
                else return( ERR_X509_KEY_INVALID_PEM );
#else
            return( ERR_X509_FEATURE_UNAVAILABLE );
#endif
        }

        len = 0;
        ret = base64_decode( NULL, &len, s1, s2 - s1 );

        if( ret == ERR_BASE64_INVALID_CHARACTER )
            return( ret | ERR_X509_KEY_INVALID_PEM );

        if( ( buf = (unsigned char *) malloc( len ) ) == NULL )
            return( 1 );

        if( ( ret = base64_decode( buf, &len, s1, s2 - s1 ) ) != 0 )
        {
            free( buf );
            return( ret | ERR_X509_KEY_INVALID_PEM );
        }

        buflen = len;

#if !defined(NO_DES)
        if( enc != 0 )
        {
            if( pwd == NULL )
            {
                free( buf );
                return( ERR_X509_KEY_PASSWORD_REQUIRED );
            }

            x509_des3_decrypt( des3_iv, buf, buflen, pwd, pwdlen );

            if( buf[0] != 0x30 || buf[1] != 0x82 ||
                buf[4] != 0x02 || buf[5] != 0x01 )
            {
                free( buf );
                return( ERR_X509_KEY_PASSWORD_MISMATCH );
            }
        }
#endif
    }

    memset( rsa, 0, sizeof( rsa_context ) );

    p = buf;
    end = buf + buflen;

    /*
     *  RSAPrivateKey ::= SEQUENCE {
     *      version           Version,
     *      modulus           INTEGER,  -- n
     *      publicExponent    INTEGER,  -- e
     *      privateExponent   INTEGER,  -- d
     *      prime1            INTEGER,  -- p
     *      prime2            INTEGER,  -- q
     *      exponent1         INTEGER,  -- d mod (p-1)
     *      exponent2         INTEGER,  -- d mod (q-1)
     *      coefficient       INTEGER,  -- (inverse of q) mod p
     *      otherPrimeInfos   OtherPrimeInfos OPTIONAL
     *  }
     */
    if( ( ret = asn1_get_tag( &p, end, &len,
            ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
    {
        if( s1 != NULL )
            free( buf );

        rsa_free( rsa );
        return( ERR_X509_KEY_INVALID_FORMAT | ret );
    }

    end = p + len;

    if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
    {
        if( s1 != NULL )
            free( buf );

        rsa_free( rsa );
        return( ERR_X509_KEY_INVALID_FORMAT | ret );
    }

    if( rsa->ver != 0 )
    {
        if( s1 != NULL )
            free( buf );

        rsa_free( rsa );
        return( ret | ERR_X509_KEY_INVALID_VERSION );
    }

    if( ( ret = asn1_get_mpi( &p, end, &rsa->N  ) ) != 0 ||
        ( ret = asn1_get_mpi( &p, end, &rsa->E  ) ) != 0 ||
        ( ret = asn1_get_mpi( &p, end, &rsa->D  ) ) != 0 ||
        ( ret = asn1_get_mpi( &p, end, &rsa->P  ) ) != 0 ||
        ( ret = asn1_get_mpi( &p, end, &rsa->Q  ) ) != 0 ||
        ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
        ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
        ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
    {
        if( s1 != NULL )
            free( buf );

        rsa_free( rsa );
        return( ret | ERR_X509_KEY_INVALID_FORMAT );
    }

    rsa->len = ( mpi_msb( &rsa->N ) + 7 ) >> 3;

    if( p != end )
    {
        if( s1 != NULL )
            free( buf );

        rsa_free( rsa );
        return( ERR_X509_KEY_INVALID_FORMAT |
                ERR_ASN1_LENGTH_MISMATCH );
    }

    if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
    {
        if( s1 != NULL )
            free( buf );

        rsa_free( rsa );
        return( ret );
    }

    if( s1 != NULL )
        free( buf );

    return( 0 );
}

/*
 * Load and parse a private RSA key
 */
int x509_read_keyfile( rsa_context *rsa, char *path, char *pwd )
{
    int ret;
    FILE *f;
    size_t n;
    unsigned char *buf;

    if( ( f = fopen( path, "rb" ) ) == NULL )
        return( 1 );

    fseek( f, 0, SEEK_END );
    n = (size_t) ftell( f );
    fseek( f, 0, SEEK_SET );

    if( ( buf = (unsigned char *) malloc( n + 1 ) ) == NULL )
        return( 1 );

    if( fread( buf, 1, n, f ) != n )
    {
        fclose( f );
        free( buf );
        return( 1 );
    }

    buf[n] = '\0';

    if( pwd == NULL )
        ret = x509_parse_key( rsa, buf, (int) n, NULL, 0 );
    else
        ret = x509_parse_key( rsa, buf, (int) n,
                (unsigned char *) pwd, strlen( pwd ) );

    memset( buf, 0, n + 1 );
    free( buf );
    fclose( f );

    return( ret );
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -