Hello, I've got a question about OpenSSL parsing of X509 certificates using RSASSA-PSS with default parameters and non-default parameters.
For default parameters using SHA1 with MGF-SHA1, the ASN1 structure part of a certificate should be: SEQUENCE { OBJECT IDENTIFIER rsaPSS (1 2 840 113549 1 1 10) SEQUENCE {} } The empty sequence is to be interpreted according to RFC4055 in the following way: 1) Implementations that perform signature generation MUST omit the hashAlgorithm field when SHA-1 is used, indicating that the default algorithm was used. 2) Implementations that perform signature generation MUST omit the maskGenAlgorithm field when MGF1 with SHA-1 is used, indicating that the default algorithm was used. 3) (not explicitly mention in RFC) 4) Implementations that perform signature generation MUST omit the trailerField field, indicating that the default trailer field value was used. OpenSSL 1.0.1c parses such certificates in the following way: $ openssl x509 -in cert_sha1.pem -text (...) Signature Algorithm: rsassaPss Hash Algorithm: sha1 (default) Mask Algorithm: mgf1 with sha1 (default) Salt Length: 20 (default) Trailer Field: 0xbc (default) (...) According to implementation in crypto/rsa/rsa_ameth.c openssl prints hard-coded hash, mask, salt and trailer field strings. Im interpreting salt length to be represented as an integer, since SHA1 is 160 bits = 20 bytes, and the trailer field as hexadecimal due to 0x prefix. If I create another certificate using SHA256 with MGF-SHA256, a salt length of integer 32 (len of SHA256 hash block) and trailer field integer 1 (only allowed value according to RFC4055), the ASN1 structure part of the certificate should be: SEQUENCE { 13 9: OBJECT IDENTIFIER rsaPSS (1 2 840 113549 1 1 10) 24 57: SEQUENCE { 26 15: [0] { 28 13: SEQUENCE { 30 9: OBJECT IDENTIFIER sha-256 (2 16 840 1 101 3 4 2 1) 41 0: NULL : } : } 43 28: [1] { 45 26: SEQUENCE { 47 9: OBJECT IDENTIFIER pkcs1-MGF (1 2 840 113549 1 1 8) 58 13: SEQUENCE { 60 9: OBJECT IDENTIFIER sha-256 (2 16 840 1 101 3 4 2 1) 71 0: NULL : } : } : } 73 3: [2] { 75 1: INTEGER 32 : } 78 3: [3] { 80 1: INTEGER 1 : } : } : } If I parse this certificate using OpenSSL 1.0.1c, I get the following decoding of the signature algorithm: $ openssl x509 -in cert_sha256.pem -text (...) Signature Algorithm: rsassaPss Hash Algorithm: sha256 Mask Algorithm: mgf1 with sha256 Salt Length: 20 Trailer Field: 01 (...) This is the confusing part. To me it now seems both salt length and trailer field is represented as hexadecimal (although not prefixed with 0x). So there is an inconsistency here to how the salt length and trailer field is represented by OpenSSL depending on if RSASSA-PSS signature algorithm parameters are present. Suggested fixes: If salt length and trailer field is to be expressed in hexadecimal format: 1) Hexadecimal values should always be prefixed with 0x 2) The default salt length for SHA1 implementations should be represented with 0x14 (which equals int 20) 3) The only valid trailer field for RSASSA-PSS is 1, which is to be interpreted as 0xbc. If omitted, the string should contain (default). If salt length and trailer field is to be expressed in integer format: 1) Dont convert i2a in crypto/rsa/rsa_ameth.c when pss->saltLength and pss->trailerField is present. 2) The only valid trailer field for RSASSA-PSS is 1, which is to be interpreted as 0xbc. If omitted, the string should contain (default). Best regards, Frank
signature.asc
Description: This is a digitally signed message part