- Merged back bugfixes from trunk (pre 0.99-pre2):
* Corrected parsing of UTCTime dates before 1990 and after 1950
* Support more exotic OID's when parsing certificates
* Support more exotic name representations when parsing certificates
* Replaced the expired test certificates
* Do not bail out if no client certificate specified. Try to negotiate anonymous connection (Fixes ticket #12)
diff --git a/library/x509parse.c b/library/x509parse.c
index ea9748c..31cfe34 100644
--- a/library/x509parse.c
+++ b/library/x509parse.c
@@ -269,9 +269,6 @@
}
/*
- * RelativeDistinguishedName ::=
- * SET OF AttributeTypeAndValue
- *
* AttributeTypeAndValue ::= SEQUENCE {
* type AttributeType,
* value AttributeValue }
@@ -280,30 +277,18 @@
*
* AttributeValue ::= ANY DEFINED BY AttributeType
*/
-static int x509_get_name( unsigned char **p,
- const unsigned char *end,
- x509_name *cur )
+static int x509_get_attr_type_value( unsigned char **p,
+ const unsigned char *end,
+ x509_name *cur )
{
int ret, len;
- const unsigned char *end2;
x509_buf *oid;
x509_buf *val;
if( ( ret = asn1_get_tag( p, end, &len,
- ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
- return( POLARSSL_ERR_X509_CERT_INVALID_NAME | ret );
-
- end2 = end;
- end = *p + len;
-
- if( ( ret = asn1_get_tag( p, end, &len,
ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
return( POLARSSL_ERR_X509_CERT_INVALID_NAME | ret );
- if( *p + len != end )
- return( POLARSSL_ERR_X509_CERT_INVALID_NAME |
- POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
-
oid = &cur->oid;
oid->tag = **p;
@@ -334,9 +319,56 @@
cur->next = NULL;
- if( *p != end )
- return( POLARSSL_ERR_X509_CERT_INVALID_NAME |
- POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
+ return( 0 );
+}
+
+/*
+ * RelativeDistinguishedName ::=
+ * SET OF AttributeTypeAndValue
+ *
+ * AttributeTypeAndValue ::= SEQUENCE {
+ * type AttributeType,
+ * value AttributeValue }
+ *
+ * AttributeType ::= OBJECT IDENTIFIER
+ *
+ * AttributeValue ::= ANY DEFINED BY AttributeType
+ */
+static int x509_get_name( unsigned char **p,
+ const unsigned char *end,
+ x509_name *cur )
+{
+ int ret, len;
+ const unsigned char *end2;
+ x509_name *use;
+
+ if( ( ret = asn1_get_tag( p, end, &len,
+ ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
+ return( POLARSSL_ERR_X509_CERT_INVALID_NAME | ret );
+
+ end2 = end;
+ end = *p + len;
+ use = cur;
+
+ do
+ {
+ if( ( ret = x509_get_attr_type_value( p, end, use ) ) != 0 )
+ return( ret );
+
+ if( *p != end )
+ {
+ use->next = (x509_name *) malloc(
+ sizeof( x509_name ) );
+
+ if( use->next == NULL )
+ return( 1 );
+
+ memset( use->next, 0, sizeof( x509_name ) );
+
+ use = use->next;
+ }
+ }
+ while( *p != end );
/*
* recurse until end of SEQUENCE is reached
@@ -388,7 +420,7 @@
&time->hour, &time->min, &time->sec ) < 5 )
return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
- time->year += 100 * ( time->year < 90 );
+ time->year += 100 * ( time->year < 50 );
time->year += 1900;
*p += len;
@@ -462,7 +494,7 @@
x509_buf *pk_alg_oid,
mpi *N, mpi *E )
{
- int ret, len;
+ int ret, len, can_handle;
unsigned char *end2;
if( ( ret = x509_get_alg( p, end, pk_alg_oid ) ) != 0 )
@@ -471,8 +503,27 @@
/*
* only RSA public keys handled at this time
*/
- if( pk_alg_oid->len != 9 ||
- memcmp( pk_alg_oid->p, OID_PKCS1_RSA, 9 ) != 0 )
+ can_handle = 0;
+
+ if( pk_alg_oid->len == 9 &&
+ memcmp( pk_alg_oid->p, OID_PKCS1_RSA, 9 ) == 0 )
+ can_handle = 1;
+
+ if( pk_alg_oid->len == 9 &&
+ memcmp( pk_alg_oid->p, OID_PKCS1, 8 ) == 0 )
+ {
+ if( pk_alg_oid->p[8] >= 2 && pk_alg_oid->p[8] <= 5 )
+ can_handle = 1;
+
+ if ( pk_alg_oid->p[8] >= 11 && pk_alg_oid->p[8] <= 14 )
+ can_handle = 1;
+ }
+
+ if( pk_alg_oid->len == 5 &&
+ memcmp( pk_alg_oid->p, OID_RSA_SHA_OBS, 5 ) == 0 )
+ can_handle = 1;
+
+ if( can_handle == 0 )
return( POLARSSL_ERR_X509_CERT_UNKNOWN_PK_ALG );
if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
@@ -811,6 +862,12 @@
return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
}
+ if( sig_oid->len == 5 &&
+ memcmp( sig_oid->p, OID_RSA_SHA_OBS, 5 ) == 0 )
+ {
+ *sig_alg = SIG_RSA_SHA1;
+ return( 0 );
+ }
return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
}
@@ -2561,6 +2618,7 @@
ret = x509parse_verify( &clicert, &cacert, NULL, "PolarSSL Client 2", &i );
if( ret != 0 )
{
+ printf("%02x", i);
if( verbose != 0 )
printf( "failed\n" );