/* * Parse an ASN1_UTC_TIME (yearlen=2) or ASN1_GENERALIZED_TIME (yearlen=4) * field. */ static int x509_parse_time( unsigned char **p, size_t len, size_t yearlen, mbedtls_x509_time *tm ) { int ret; /* * Minimum length is 10 or 12 depending on yearlen */ if ( len < yearlen + 8 ) return ( MBEDTLS_ERR_X509_INVALID_DATE ); len -= yearlen + 8; /* * Parse year, month, day, hour, minute */ CHECK( x509_parse_int( p, yearlen, &tm->year ) ); if ( 2 == yearlen ) { if ( tm->year < 50 ) tm->year += 100; tm->year += 1900; } CHECK( x509_parse_int( p, 2, &tm->mon ) ); CHECK( x509_parse_int( p, 2, &tm->day ) ); CHECK( x509_parse_int( p, 2, &tm->hour ) ); CHECK( x509_parse_int( p, 2, &tm->min ) ); /* * Parse seconds if present */ if ( len >= 2 ) { CHECK( x509_parse_int( p, 2, &tm->sec ) ); len -= 2; } else return ( MBEDTLS_ERR_X509_INVALID_DATE ); /* * Parse trailing 'Z' if present */ if ( 1 == len && 'Z' == **p ) { (*p)++; len--; } /* * We should have parsed all characters at this point */ if ( 0 != len ) return ( MBEDTLS_ERR_X509_INVALID_DATE ); CHECK( x509_date_is_valid( tm ) ); return ( 0 ); }
/* * Time ::= CHOICE { * utcTime UTCTime, * generalTime GeneralizedTime } */ int mbedtls_x509_get_time( unsigned char **p, const unsigned char *end, mbedtls_x509_time *time ) { int ret; size_t len; unsigned char tag; if( ( end - *p ) < 1 ) return( MBEDTLS_ERR_X509_INVALID_DATE + MBEDTLS_ERR_ASN1_OUT_OF_DATA ); tag = **p; if( tag == MBEDTLS_ASN1_UTC_TIME ) { (*p)++; ret = mbedtls_asn1_get_len( p, end, &len ); if( ret != 0 ) return( MBEDTLS_ERR_X509_INVALID_DATE + ret ); CHECK( x509_parse_int( p, 2, &time->year ) ); CHECK( x509_parse_int( p, 2, &time->mon ) ); CHECK( x509_parse_int( p, 2, &time->day ) ); CHECK( x509_parse_int( p, 2, &time->hour ) ); CHECK( x509_parse_int( p, 2, &time->min ) ); if( len > 10 ) CHECK( x509_parse_int( p, 2, &time->sec ) ); if( len > 12 && *(*p)++ != 'Z' ) return( MBEDTLS_ERR_X509_INVALID_DATE ); time->year += 100 * ( time->year < 50 ); time->year += 1900; CHECK( x509_date_is_valid( time ) ); return( 0 ); } else if( tag == MBEDTLS_ASN1_GENERALIZED_TIME ) { (*p)++; ret = mbedtls_asn1_get_len( p, end, &len ); if( ret != 0 ) return( MBEDTLS_ERR_X509_INVALID_DATE + ret ); CHECK( x509_parse_int( p, 4, &time->year ) ); CHECK( x509_parse_int( p, 2, &time->mon ) ); CHECK( x509_parse_int( p, 2, &time->day ) ); CHECK( x509_parse_int( p, 2, &time->hour ) ); CHECK( x509_parse_int( p, 2, &time->min ) ); if( len > 12 ) CHECK( x509_parse_int( p, 2, &time->sec ) ); if( len > 14 && *(*p)++ != 'Z' ) return( MBEDTLS_ERR_X509_INVALID_DATE ); CHECK( x509_date_is_valid( time ) ); return( 0 ); } else return( MBEDTLS_ERR_X509_INVALID_DATE + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); }