|  | @@ -20,8 +20,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
 | 
		
	
		
			
			| 20 | 20 |  
 | 
		
	
		
			
			| 21 | 21 |  #include <stdlib.h>
 | 
		
	
		
			
			| 22 | 22 |  #include <string.h>
 | 
		
	
		
			
			| 23 |  | -#include <ctype.h>
 | 
		
	
		
			
			| 24 |  | -#include <time.h>
 | 
		
	
		
			
			| 25 | 23 |  #include <errno.h>
 | 
		
	
		
			
			| 26 | 24 |  #include <assert.h>
 | 
		
	
		
			
			| 27 | 25 |  #include <ipxe/list.h>
 | 
		
	
	
		
			
			|  | @@ -60,10 +58,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
 | 
		
	
		
			
			| 60 | 58 |  	__einfo_error ( EINFO_EINVAL_BIT_STRING )
 | 
		
	
		
			
			| 61 | 59 |  #define EINFO_EINVAL_BIT_STRING \
 | 
		
	
		
			
			| 62 | 60 |  	__einfo_uniqify ( EINFO_EINVAL, 0x02, "Invalid bit string" )
 | 
		
	
		
			
			| 63 |  | -#define EINVAL_TIME \
 | 
		
	
		
			
			| 64 |  | -	__einfo_error ( EINFO_EINVAL_TIME )
 | 
		
	
		
			
			| 65 |  | -#define EINFO_EINVAL_TIME \
 | 
		
	
		
			
			| 66 |  | -	__einfo_uniqify ( EINFO_EINVAL, 0x03, "Invalid time" )
 | 
		
	
		
			
			| 67 | 61 |  #define EINVAL_ALGORITHM_MISMATCH \
 | 
		
	
		
			
			| 68 | 62 |  	__einfo_error ( EINFO_EINVAL_ALGORITHM_MISMATCH )
 | 
		
	
		
			
			| 69 | 63 |  #define EINFO_EINVAL_ALGORITHM_MISMATCH \
 | 
		
	
	
		
			
			|  | @@ -301,114 +295,6 @@ static int x509_parse_integral_bit_string ( struct x509_certificate *cert,
 | 
		
	
		
			
			| 301 | 295 |  	return 0;
 | 
		
	
		
			
			| 302 | 296 |  }
 | 
		
	
		
			
			| 303 | 297 |  
 | 
		
	
		
			
			| 304 |  | -/**
 | 
		
	
		
			
			| 305 |  | - * Parse X.509 certificate time
 | 
		
	
		
			
			| 306 |  | - *
 | 
		
	
		
			
			| 307 |  | - * @v cert		X.509 certificate
 | 
		
	
		
			
			| 308 |  | - * @v time		Time to fill in
 | 
		
	
		
			
			| 309 |  | - * @v raw		ASN.1 cursor
 | 
		
	
		
			
			| 310 |  | - * @ret rc		Return status code
 | 
		
	
		
			
			| 311 |  | - *
 | 
		
	
		
			
			| 312 |  | - * RFC 5280 section 4.1.2.5 places several restrictions on the allowed
 | 
		
	
		
			
			| 313 |  | - * formats for UTCTime and GeneralizedTime, and mandates the
 | 
		
	
		
			
			| 314 |  | - * interpretation of centuryless year values.
 | 
		
	
		
			
			| 315 |  | - */
 | 
		
	
		
			
			| 316 |  | -static int x509_parse_time ( struct x509_certificate *cert,
 | 
		
	
		
			
			| 317 |  | -			     struct x509_time *time,
 | 
		
	
		
			
			| 318 |  | -			     const struct asn1_cursor *raw ) {
 | 
		
	
		
			
			| 319 |  | -	struct asn1_cursor cursor;
 | 
		
	
		
			
			| 320 |  | -	unsigned int have_century;
 | 
		
	
		
			
			| 321 |  | -	unsigned int type;
 | 
		
	
		
			
			| 322 |  | -	union {
 | 
		
	
		
			
			| 323 |  | -		struct {
 | 
		
	
		
			
			| 324 |  | -			uint8_t century;
 | 
		
	
		
			
			| 325 |  | -			uint8_t year;
 | 
		
	
		
			
			| 326 |  | -			uint8_t month;
 | 
		
	
		
			
			| 327 |  | -			uint8_t day;
 | 
		
	
		
			
			| 328 |  | -			uint8_t hour;
 | 
		
	
		
			
			| 329 |  | -			uint8_t minute;
 | 
		
	
		
			
			| 330 |  | -			uint8_t second;
 | 
		
	
		
			
			| 331 |  | -		} __attribute__ (( packed )) named;
 | 
		
	
		
			
			| 332 |  | -		uint8_t raw[7];
 | 
		
	
		
			
			| 333 |  | -	} pairs;
 | 
		
	
		
			
			| 334 |  | -	struct tm tm;
 | 
		
	
		
			
			| 335 |  | -	const uint8_t *data;
 | 
		
	
		
			
			| 336 |  | -	size_t remaining;
 | 
		
	
		
			
			| 337 |  | -	unsigned int tens;
 | 
		
	
		
			
			| 338 |  | -	unsigned int units;
 | 
		
	
		
			
			| 339 |  | -	unsigned int i;
 | 
		
	
		
			
			| 340 |  | -	int rc;
 | 
		
	
		
			
			| 341 |  | -
 | 
		
	
		
			
			| 342 |  | -	/* Determine time format utcTime/generalizedTime */
 | 
		
	
		
			
			| 343 |  | -	memcpy ( &cursor, raw, sizeof ( cursor ) );
 | 
		
	
		
			
			| 344 |  | -	type = asn1_type ( &cursor );
 | 
		
	
		
			
			| 345 |  | -	switch ( type ) {
 | 
		
	
		
			
			| 346 |  | -	case ASN1_UTC_TIME:
 | 
		
	
		
			
			| 347 |  | -		have_century = 0;
 | 
		
	
		
			
			| 348 |  | -		break;
 | 
		
	
		
			
			| 349 |  | -	case ASN1_GENERALIZED_TIME:
 | 
		
	
		
			
			| 350 |  | -		have_century = 1;
 | 
		
	
		
			
			| 351 |  | -		break;
 | 
		
	
		
			
			| 352 |  | -	default:
 | 
		
	
		
			
			| 353 |  | -		DBGC ( cert, "X509 %p invalid time type %02x\n", cert, type );
 | 
		
	
		
			
			| 354 |  | -		DBGC_HDA ( cert, 0, raw->data, raw->len );
 | 
		
	
		
			
			| 355 |  | -		return -EINVAL_TIME;
 | 
		
	
		
			
			| 356 |  | -	}
 | 
		
	
		
			
			| 357 |  | -
 | 
		
	
		
			
			| 358 |  | -	/* Enter utcTime/generalizedTime */
 | 
		
	
		
			
			| 359 |  | -	if ( ( rc = asn1_enter ( &cursor, type ) ) != 0 ) {
 | 
		
	
		
			
			| 360 |  | -		DBGC ( cert, "X509 %p cannot locate %s time:\n", cert,
 | 
		
	
		
			
			| 361 |  | -		       ( ( type == ASN1_UTC_TIME ) ? "UTC" : "generalized" ) );
 | 
		
	
		
			
			| 362 |  | -		DBGC_HDA ( cert, 0, raw->data, raw->len );
 | 
		
	
		
			
			| 363 |  | -		return rc;
 | 
		
	
		
			
			| 364 |  | -	}
 | 
		
	
		
			
			| 365 |  | -
 | 
		
	
		
			
			| 366 |  | -	/* Parse digit string a pair at a time */
 | 
		
	
		
			
			| 367 |  | -	data = cursor.data;
 | 
		
	
		
			
			| 368 |  | -	remaining = cursor.len;
 | 
		
	
		
			
			| 369 |  | -	for ( i = ( have_century ? 0 : 1 ) ; i < sizeof ( pairs.raw ) ; i++ ) {
 | 
		
	
		
			
			| 370 |  | -		if ( remaining < 2 ) {
 | 
		
	
		
			
			| 371 |  | -			DBGC ( cert, "X509 %p invalid time:\n", cert );
 | 
		
	
		
			
			| 372 |  | -			DBGC_HDA ( cert, 0, raw->data, raw->len );
 | 
		
	
		
			
			| 373 |  | -			return -EINVAL_TIME;
 | 
		
	
		
			
			| 374 |  | -		}
 | 
		
	
		
			
			| 375 |  | -		tens = data[0];
 | 
		
	
		
			
			| 376 |  | -		units = data[1];
 | 
		
	
		
			
			| 377 |  | -		if ( ! ( isdigit ( tens ) && isdigit ( units ) ) ) {
 | 
		
	
		
			
			| 378 |  | -			DBGC ( cert, "X509 %p invalid time:\n", cert );
 | 
		
	
		
			
			| 379 |  | -			DBGC_HDA ( cert, 0, raw->data, raw->len );
 | 
		
	
		
			
			| 380 |  | -			return -EINVAL_TIME;
 | 
		
	
		
			
			| 381 |  | -		}
 | 
		
	
		
			
			| 382 |  | -		pairs.raw[i] = ( ( 10 * ( tens - '0' ) ) + ( units - '0' ) );
 | 
		
	
		
			
			| 383 |  | -		data += 2;
 | 
		
	
		
			
			| 384 |  | -		remaining -= 2;
 | 
		
	
		
			
			| 385 |  | -	}
 | 
		
	
		
			
			| 386 |  | -
 | 
		
	
		
			
			| 387 |  | -	/* Determine century if applicable */
 | 
		
	
		
			
			| 388 |  | -	if ( ! have_century )
 | 
		
	
		
			
			| 389 |  | -		pairs.named.century = ( ( pairs.named.year >= 50 ) ? 19 : 20 );
 | 
		
	
		
			
			| 390 |  | -
 | 
		
	
		
			
			| 391 |  | -	/* Check for trailing "Z" */
 | 
		
	
		
			
			| 392 |  | -	if ( ( remaining != 1 ) || ( data[0] != 'Z' ) ) {
 | 
		
	
		
			
			| 393 |  | -		DBGC ( cert, "X509 %p invalid time:\n", cert );
 | 
		
	
		
			
			| 394 |  | -		DBGC_HDA ( cert, 0, raw->data, raw->len );
 | 
		
	
		
			
			| 395 |  | -		return -EINVAL_TIME;
 | 
		
	
		
			
			| 396 |  | -	}
 | 
		
	
		
			
			| 397 |  | -
 | 
		
	
		
			
			| 398 |  | -	/* Fill in time */
 | 
		
	
		
			
			| 399 |  | -	tm.tm_year = ( ( ( pairs.named.century - 19 ) * 100 ) +
 | 
		
	
		
			
			| 400 |  | -		       pairs.named.year );
 | 
		
	
		
			
			| 401 |  | -	tm.tm_mon = ( pairs.named.month - 1 );
 | 
		
	
		
			
			| 402 |  | -	tm.tm_mday = pairs.named.day;
 | 
		
	
		
			
			| 403 |  | -	tm.tm_hour = pairs.named.hour;
 | 
		
	
		
			
			| 404 |  | -	tm.tm_min = pairs.named.minute;
 | 
		
	
		
			
			| 405 |  | -	tm.tm_sec = pairs.named.second;
 | 
		
	
		
			
			| 406 |  | -
 | 
		
	
		
			
			| 407 |  | -	/* Convert to seconds since the Epoch */
 | 
		
	
		
			
			| 408 |  | -	time->time = mktime ( &tm );
 | 
		
	
		
			
			| 409 |  | -
 | 
		
	
		
			
			| 410 |  | -	return 0;
 | 
		
	
		
			
			| 411 |  | -}
 | 
		
	
		
			
			| 412 | 298 |  
 | 
		
	
		
			
			| 413 | 299 |  /**
 | 
		
	
		
			
			| 414 | 300 |   * Parse X.509 certificate version
 | 
		
	
	
		
			
			|  | @@ -520,15 +406,23 @@ static int x509_parse_validity ( struct x509_certificate *cert,
 | 
		
	
		
			
			| 520 | 406 |  	asn1_enter ( &cursor, ASN1_SEQUENCE );
 | 
		
	
		
			
			| 521 | 407 |  
 | 
		
	
		
			
			| 522 | 408 |  	/* Parse notBefore */
 | 
		
	
		
			
			| 523 |  | -	if ( ( rc = x509_parse_time ( cert, not_before, &cursor ) ) != 0 )
 | 
		
	
		
			
			|  | 409 | +	if ( ( rc = asn1_generalized_time ( &cursor,
 | 
		
	
		
			
			|  | 410 | +					    ¬_before->time ) ) != 0 ) {
 | 
		
	
		
			
			|  | 411 | +		DBGC ( cert, "X509 %p cannot parse notBefore: %s\n",
 | 
		
	
		
			
			|  | 412 | +		       cert, strerror ( rc ) );
 | 
		
	
		
			
			| 524 | 413 |  		return rc;
 | 
		
	
		
			
			|  | 414 | +	}
 | 
		
	
		
			
			| 525 | 415 |  	DBGC2 ( cert, "X509 %p valid from time %lld\n",
 | 
		
	
		
			
			| 526 | 416 |  		cert, not_before->time );
 | 
		
	
		
			
			| 527 | 417 |  	asn1_skip_any ( &cursor );
 | 
		
	
		
			
			| 528 | 418 |  
 | 
		
	
		
			
			| 529 | 419 |  	/* Parse notAfter */
 | 
		
	
		
			
			| 530 |  | -	if ( ( rc = x509_parse_time ( cert, not_after, &cursor ) ) != 0 )
 | 
		
	
		
			
			|  | 420 | +	if ( ( rc = asn1_generalized_time ( &cursor,
 | 
		
	
		
			
			|  | 421 | +					    ¬_after->time ) ) != 0 ) {
 | 
		
	
		
			
			|  | 422 | +		DBGC ( cert, "X509 %p cannot parse notAfter: %s\n",
 | 
		
	
		
			
			|  | 423 | +		       cert, strerror ( rc ) );
 | 
		
	
		
			
			| 531 | 424 |  		return rc;
 | 
		
	
		
			
			|  | 425 | +	}
 | 
		
	
		
			
			| 532 | 426 |  	DBGC2 ( cert, "X509 %p valid until time %lld\n",
 | 
		
	
		
			
			| 533 | 427 |  		cert, not_after->time );
 | 
		
	
		
			
			| 534 | 428 |  
 |