|  | @@ -49,10 +49,10 @@ FILE_LICENCE ( GPL2_OR_LATER );
 | 
		
	
		
			
			| 49 | 49 |  	__einfo_error ( EINFO_ENOTSUP_EXTENSION )
 | 
		
	
		
			
			| 50 | 50 |  #define EINFO_ENOTSUP_EXTENSION \
 | 
		
	
		
			
			| 51 | 51 |  	__einfo_uniqify ( EINFO_ENOTSUP, 0x02, "Unsupported extension" )
 | 
		
	
		
			
			| 52 |  | -#define EINVAL_NON_SIGNATURE \
 | 
		
	
		
			
			| 53 |  | -	__einfo_error ( EINFO_EINVAL_NON_SIGNATURE )
 | 
		
	
		
			
			| 54 |  | -#define EINFO_EINVAL_NON_SIGNATURE \
 | 
		
	
		
			
			| 55 |  | -	__einfo_uniqify ( EINFO_EINVAL, 0x01, "Not a signature algorithm" )
 | 
		
	
		
			
			|  | 52 | +#define EINVAL_ALGORITHM \
 | 
		
	
		
			
			|  | 53 | +	__einfo_error ( EINFO_EINVAL_ALGORITHM )
 | 
		
	
		
			
			|  | 54 | +#define EINFO_EINVAL_ALGORITHM \
 | 
		
	
		
			
			|  | 55 | +	__einfo_uniqify ( EINFO_EINVAL, 0x01, "Invalid algorithm type" )
 | 
		
	
		
			
			| 56 | 56 |  #define EINVAL_BIT_STRING \
 | 
		
	
		
			
			| 57 | 57 |  	__einfo_error ( EINFO_EINVAL_BIT_STRING )
 | 
		
	
		
			
			| 58 | 58 |  #define EINFO_EINVAL_BIT_STRING \
 | 
		
	
	
		
			
			|  | @@ -101,70 +101,6 @@ static uint8_t oid_common_name[] = { ASN1_OID_COMMON_NAME };
 | 
		
	
		
			
			| 101 | 101 |  static struct asn1_cursor oid_common_name_cursor =
 | 
		
	
		
			
			| 102 | 102 |  	ASN1_OID_CURSOR ( oid_common_name );
 | 
		
	
		
			
			| 103 | 103 |  
 | 
		
	
		
			
			| 104 |  | -/** "rsaEncryption" object identifier */
 | 
		
	
		
			
			| 105 |  | -static uint8_t oid_rsa_encryption[] = { ASN1_OID_RSAENCRYPTION };
 | 
		
	
		
			
			| 106 |  | -
 | 
		
	
		
			
			| 107 |  | -/** "md5WithRSAEncryption" object identifier */
 | 
		
	
		
			
			| 108 |  | -static uint8_t oid_md5_with_rsa_encryption[] =
 | 
		
	
		
			
			| 109 |  | -	{ ASN1_OID_MD5WITHRSAENCRYPTION };
 | 
		
	
		
			
			| 110 |  | -
 | 
		
	
		
			
			| 111 |  | -/** "sha1WithRSAEncryption" object identifier */
 | 
		
	
		
			
			| 112 |  | -static uint8_t oid_sha1_with_rsa_encryption[] =
 | 
		
	
		
			
			| 113 |  | -	{ ASN1_OID_SHA1WITHRSAENCRYPTION };
 | 
		
	
		
			
			| 114 |  | -
 | 
		
	
		
			
			| 115 |  | -/** "sha256WithRSAEncryption" object identifier */
 | 
		
	
		
			
			| 116 |  | -static uint8_t oid_sha256_with_rsa_encryption[] =
 | 
		
	
		
			
			| 117 |  | -	{ ASN1_OID_SHA256WITHRSAENCRYPTION };
 | 
		
	
		
			
			| 118 |  | -
 | 
		
	
		
			
			| 119 |  | -/** Supported algorithms */
 | 
		
	
		
			
			| 120 |  | -static struct x509_algorithm x509_algorithms[] = {
 | 
		
	
		
			
			| 121 |  | -	{
 | 
		
	
		
			
			| 122 |  | -		.name = "rsaEncryption",
 | 
		
	
		
			
			| 123 |  | -		.pubkey = &rsa_algorithm,
 | 
		
	
		
			
			| 124 |  | -		.digest = NULL,
 | 
		
	
		
			
			| 125 |  | -		.oid = ASN1_OID_CURSOR ( oid_rsa_encryption ),
 | 
		
	
		
			
			| 126 |  | -	},
 | 
		
	
		
			
			| 127 |  | -	{
 | 
		
	
		
			
			| 128 |  | -		.name = "md5WithRSAEncryption",
 | 
		
	
		
			
			| 129 |  | -		.pubkey = &rsa_algorithm,
 | 
		
	
		
			
			| 130 |  | -		.digest = &md5_algorithm,
 | 
		
	
		
			
			| 131 |  | -		.oid = ASN1_OID_CURSOR ( oid_md5_with_rsa_encryption ),
 | 
		
	
		
			
			| 132 |  | -	},
 | 
		
	
		
			
			| 133 |  | -	{
 | 
		
	
		
			
			| 134 |  | -		.name = "sha1WithRSAEncryption",
 | 
		
	
		
			
			| 135 |  | -		.pubkey = &rsa_algorithm,
 | 
		
	
		
			
			| 136 |  | -		.digest = &sha1_algorithm,
 | 
		
	
		
			
			| 137 |  | -		.oid = ASN1_OID_CURSOR ( oid_sha1_with_rsa_encryption ),
 | 
		
	
		
			
			| 138 |  | -	},
 | 
		
	
		
			
			| 139 |  | -	{
 | 
		
	
		
			
			| 140 |  | -		.name = "sha256WithRSAEncryption",
 | 
		
	
		
			
			| 141 |  | -		.pubkey = &rsa_algorithm,
 | 
		
	
		
			
			| 142 |  | -		.digest = &sha256_algorithm,
 | 
		
	
		
			
			| 143 |  | -		.oid = ASN1_OID_CURSOR ( oid_sha256_with_rsa_encryption ),
 | 
		
	
		
			
			| 144 |  | -	},
 | 
		
	
		
			
			| 145 |  | -};
 | 
		
	
		
			
			| 146 |  | -
 | 
		
	
		
			
			| 147 |  | -/**
 | 
		
	
		
			
			| 148 |  | - * Identify X.509 algorithm by OID
 | 
		
	
		
			
			| 149 |  | - *
 | 
		
	
		
			
			| 150 |  | - * @v oid		OID
 | 
		
	
		
			
			| 151 |  | - * @ret algorithm	Algorithm, or NULL
 | 
		
	
		
			
			| 152 |  | - */
 | 
		
	
		
			
			| 153 |  | -static struct x509_algorithm *
 | 
		
	
		
			
			| 154 |  | -x509_find_algorithm ( const struct asn1_cursor *oid ) {
 | 
		
	
		
			
			| 155 |  | -	struct x509_algorithm *algorithm;
 | 
		
	
		
			
			| 156 |  | -	unsigned int i;
 | 
		
	
		
			
			| 157 |  | -
 | 
		
	
		
			
			| 158 |  | -	for ( i = 0 ; i < ( sizeof ( x509_algorithms ) /
 | 
		
	
		
			
			| 159 |  | -			    sizeof ( x509_algorithms[0] ) ) ; i++ ) {
 | 
		
	
		
			
			| 160 |  | -		algorithm = &x509_algorithms[i];
 | 
		
	
		
			
			| 161 |  | -		if ( asn1_compare ( &algorithm->oid, oid ) == 0 )
 | 
		
	
		
			
			| 162 |  | -			return algorithm;
 | 
		
	
		
			
			| 163 |  | -	}
 | 
		
	
		
			
			| 164 |  | -
 | 
		
	
		
			
			| 165 |  | -	return NULL;
 | 
		
	
		
			
			| 166 |  | -}
 | 
		
	
		
			
			| 167 |  | -
 | 
		
	
		
			
			| 168 | 104 |  /**
 | 
		
	
		
			
			| 169 | 105 |   * Parse X.509 certificate algorithm
 | 
		
	
		
			
			| 170 | 106 |   *
 | 
		
	
	
		
			
			|  | @@ -173,29 +109,24 @@ x509_find_algorithm ( const struct asn1_cursor *oid ) {
 | 
		
	
		
			
			| 173 | 109 |   * @v raw		ASN.1 cursor
 | 
		
	
		
			
			| 174 | 110 |   * @ret rc		Return status code
 | 
		
	
		
			
			| 175 | 111 |   */
 | 
		
	
		
			
			| 176 |  | -static int x509_parse_algorithm ( struct x509_certificate *cert,
 | 
		
	
		
			
			| 177 |  | -				  struct x509_algorithm **algorithm,
 | 
		
	
		
			
			|  | 112 | +int x509_parse_pubkey_algorithm ( struct x509_certificate *cert,
 | 
		
	
		
			
			|  | 113 | +				  struct asn1_algorithm **algorithm,
 | 
		
	
		
			
			| 178 | 114 |  				  const struct asn1_cursor *raw ) {
 | 
		
	
		
			
			| 179 |  | -	struct asn1_cursor cursor;
 | 
		
	
		
			
			| 180 |  | -	int rc;
 | 
		
	
		
			
			| 181 | 115 |  
 | 
		
	
		
			
			| 182 |  | -	/* Enter signatureAlgorithm */
 | 
		
	
		
			
			| 183 |  | -	memcpy ( &cursor, raw, sizeof ( cursor ) );
 | 
		
	
		
			
			| 184 |  | -	asn1_enter ( &cursor, ASN1_SEQUENCE );
 | 
		
	
		
			
			| 185 |  | -
 | 
		
	
		
			
			| 186 |  | -	/* Enter algorithm */
 | 
		
	
		
			
			| 187 |  | -	if ( ( rc = asn1_enter ( &cursor, ASN1_OID ) ) != 0 ) {
 | 
		
	
		
			
			| 188 |  | -		DBGC ( cert, "X509 %p cannot locate algorithm:\n", cert );
 | 
		
	
		
			
			|  | 116 | +	/* Parse algorithm */
 | 
		
	
		
			
			|  | 117 | +	*algorithm = asn1_algorithm ( raw );
 | 
		
	
		
			
			|  | 118 | +	if ( ! (*algorithm) ) {
 | 
		
	
		
			
			|  | 119 | +		DBGC ( cert, "X509 %p unrecognised algorithm:\n", cert );
 | 
		
	
		
			
			| 189 | 120 |  		DBGC_HDA ( cert, 0, raw->data, raw->len );
 | 
		
	
		
			
			| 190 |  | -		return rc;
 | 
		
	
		
			
			|  | 121 | +		return -ENOTSUP_ALGORITHM;
 | 
		
	
		
			
			| 191 | 122 |  	}
 | 
		
	
		
			
			| 192 | 123 |  
 | 
		
	
		
			
			| 193 |  | -	/* Identify algorithm */
 | 
		
	
		
			
			| 194 |  | -	*algorithm = x509_find_algorithm ( &cursor );
 | 
		
	
		
			
			| 195 |  | -	if ( ! *algorithm ) {
 | 
		
	
		
			
			| 196 |  | -		DBGC ( cert, "X509 %p unsupported algorithm:\n", cert );
 | 
		
	
		
			
			| 197 |  | -		DBGC_HDA ( cert, 0, cursor.data, cursor.len );
 | 
		
	
		
			
			| 198 |  | -		return -ENOTSUP_ALGORITHM;
 | 
		
	
		
			
			|  | 124 | +	/* Check algorithm has a public key */
 | 
		
	
		
			
			|  | 125 | +	if ( ! (*algorithm)->pubkey ) {
 | 
		
	
		
			
			|  | 126 | +		DBGC ( cert, "X509 %p algorithm %s is not a public-key "
 | 
		
	
		
			
			|  | 127 | +		       "algorithm:\n", cert, (*algorithm)->name );
 | 
		
	
		
			
			|  | 128 | +		DBGC_HDA ( cert, 0, raw->data, raw->len );
 | 
		
	
		
			
			|  | 129 | +		return -EINVAL_ALGORITHM;
 | 
		
	
		
			
			| 199 | 130 |  	}
 | 
		
	
		
			
			| 200 | 131 |  
 | 
		
	
		
			
			| 201 | 132 |  	return 0;
 | 
		
	
	
		
			
			|  | @@ -210,20 +141,21 @@ static int x509_parse_algorithm ( struct x509_certificate *cert,
 | 
		
	
		
			
			| 210 | 141 |   * @ret rc		Return status code
 | 
		
	
		
			
			| 211 | 142 |   */
 | 
		
	
		
			
			| 212 | 143 |  static int x509_parse_signature_algorithm ( struct x509_certificate *cert,
 | 
		
	
		
			
			| 213 |  | -					    struct x509_algorithm **algorithm,
 | 
		
	
		
			
			|  | 144 | +					    struct asn1_algorithm **algorithm,
 | 
		
	
		
			
			| 214 | 145 |  					    const struct asn1_cursor *raw ) {
 | 
		
	
		
			
			| 215 | 146 |  	int rc;
 | 
		
	
		
			
			| 216 | 147 |  
 | 
		
	
		
			
			| 217 | 148 |  	/* Parse algorithm */
 | 
		
	
		
			
			| 218 |  | -	if ( ( rc = x509_parse_algorithm ( cert, algorithm, raw ) ) != 0 )
 | 
		
	
		
			
			|  | 149 | +	if ( ( rc = x509_parse_pubkey_algorithm ( cert, algorithm,
 | 
		
	
		
			
			|  | 150 | +						  raw ) ) != 0 )
 | 
		
	
		
			
			| 219 | 151 |  		return rc;
 | 
		
	
		
			
			| 220 | 152 |  
 | 
		
	
		
			
			| 221 | 153 |  	/* Check algorithm is a signature algorithm */
 | 
		
	
		
			
			| 222 |  | -	if ( ! x509_is_signature_algorithm ( *algorithm ) ) {
 | 
		
	
		
			
			|  | 154 | +	if ( ! (*algorithm)->digest ) {
 | 
		
	
		
			
			| 223 | 155 |  		DBGC ( cert, "X509 %p algorithm %s is not a signature "
 | 
		
	
		
			
			| 224 | 156 |  		       "algorithm:\n", cert, (*algorithm)->name );
 | 
		
	
		
			
			| 225 | 157 |  		DBGC_HDA ( cert, 0, raw->data, raw->len );
 | 
		
	
		
			
			| 226 |  | -		return -EINVAL_NON_SIGNATURE;
 | 
		
	
		
			
			|  | 158 | +		return -EINVAL_ALGORITHM;
 | 
		
	
		
			
			| 227 | 159 |  	}
 | 
		
	
		
			
			| 228 | 160 |  
 | 
		
	
		
			
			| 229 | 161 |  	return 0;
 | 
		
	
	
		
			
			|  | @@ -600,7 +532,7 @@ static int x509_parse_subject ( struct x509_certificate *cert,
 | 
		
	
		
			
			| 600 | 532 |  static int x509_parse_public_key ( struct x509_certificate *cert,
 | 
		
	
		
			
			| 601 | 533 |  				   const struct asn1_cursor *raw ) {
 | 
		
	
		
			
			| 602 | 534 |  	struct x509_public_key *public_key = &cert->subject.public_key;
 | 
		
	
		
			
			| 603 |  | -	struct x509_algorithm **algorithm = &public_key->algorithm;
 | 
		
	
		
			
			|  | 535 | +	struct asn1_algorithm **algorithm = &public_key->algorithm;
 | 
		
	
		
			
			| 604 | 536 |  	struct asn1_cursor cursor;
 | 
		
	
		
			
			| 605 | 537 |  	int rc;
 | 
		
	
		
			
			| 606 | 538 |  
 | 
		
	
	
		
			
			|  | @@ -613,7 +545,8 @@ static int x509_parse_public_key ( struct x509_certificate *cert,
 | 
		
	
		
			
			| 613 | 545 |  	asn1_enter ( &cursor, ASN1_SEQUENCE );
 | 
		
	
		
			
			| 614 | 546 |  
 | 
		
	
		
			
			| 615 | 547 |  	/* Parse algorithm */
 | 
		
	
		
			
			| 616 |  | -	if ( ( rc = x509_parse_algorithm ( cert, algorithm, &cursor ) ) != 0 )
 | 
		
	
		
			
			|  | 548 | +	if ( ( rc = x509_parse_pubkey_algorithm ( cert, algorithm,
 | 
		
	
		
			
			|  | 549 | +						  &cursor ) ) != 0 )
 | 
		
	
		
			
			| 617 | 550 |  		return rc;
 | 
		
	
		
			
			| 618 | 551 |  	DBGC ( cert, "X509 %p public key algorithm is %s\n",
 | 
		
	
		
			
			| 619 | 552 |  	       cert, (*algorithm)->name );
 | 
		
	
	
		
			
			|  | @@ -866,7 +799,7 @@ static int x509_parse_extensions ( struct x509_certificate *cert,
 | 
		
	
		
			
			| 866 | 799 |   */
 | 
		
	
		
			
			| 867 | 800 |  static int x509_parse_tbscertificate ( struct x509_certificate *cert,
 | 
		
	
		
			
			| 868 | 801 |  				       const struct asn1_cursor *raw ) {
 | 
		
	
		
			
			| 869 |  | -	struct x509_algorithm **algorithm = &cert->signature_algorithm;
 | 
		
	
		
			
			|  | 802 | +	struct asn1_algorithm **algorithm = &cert->signature_algorithm;
 | 
		
	
		
			
			| 870 | 803 |  	struct asn1_cursor cursor;
 | 
		
	
		
			
			| 871 | 804 |  	int rc;
 | 
		
	
		
			
			| 872 | 805 |  
 | 
		
	
	
		
			
			|  | @@ -933,7 +866,7 @@ static int x509_parse_tbscertificate ( struct x509_certificate *cert,
 | 
		
	
		
			
			| 933 | 866 |   */
 | 
		
	
		
			
			| 934 | 867 |  int x509_parse ( struct x509_certificate *cert, const void *data, size_t len ) {
 | 
		
	
		
			
			| 935 | 868 |  	struct x509_signature *signature = &cert->signature;
 | 
		
	
		
			
			| 936 |  | -	struct x509_algorithm **signature_algorithm = &signature->algorithm;
 | 
		
	
		
			
			|  | 869 | +	struct asn1_algorithm **signature_algorithm = &signature->algorithm;
 | 
		
	
		
			
			| 937 | 870 |  	struct x509_bit_string *signature_value = &signature->value;
 | 
		
	
		
			
			| 938 | 871 |  	struct asn1_cursor cursor;
 | 
		
	
		
			
			| 939 | 872 |  	int rc;
 | 
		
	
	
		
			
			|  | @@ -991,7 +924,7 @@ int x509_parse ( struct x509_certificate *cert, const void *data, size_t len ) {
 | 
		
	
		
			
			| 991 | 924 |  static int x509_check_signature ( struct x509_certificate *cert,
 | 
		
	
		
			
			| 992 | 925 |  				  struct x509_public_key *public_key ) {
 | 
		
	
		
			
			| 993 | 926 |  	struct x509_signature *signature = &cert->signature;
 | 
		
	
		
			
			| 994 |  | -	struct x509_algorithm *algorithm = signature->algorithm;
 | 
		
	
		
			
			|  | 927 | +	struct asn1_algorithm *algorithm = signature->algorithm;
 | 
		
	
		
			
			| 995 | 928 |  	struct digest_algorithm *digest = algorithm->digest;
 | 
		
	
		
			
			| 996 | 929 |  	struct pubkey_algorithm *pubkey = algorithm->pubkey;
 | 
		
	
		
			
			| 997 | 930 |  	uint8_t digest_ctx[ digest->ctxsize ];
 |