📄 x509read_c.htm
字号:
}
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 + -