How to convert from a ESSCertId certHash to a x509SKI? - cryptography

In a RFC 3161 Timestamp Token, How can I convert the certHash of the ESSCertID into a x509SKI?
For example, in this timestamp token the certHash is hex-encoded as
5A25B4B5D82C19118C496917A4EA53309A859DDB
which converted to base-64 is
WiW0tdgsGRGMSWkXpOpTMJqFnds=
but I know from the EU Trusted List that the x509SKI should be
t0SsyqkWH9a3+KEASdguv/5fY8g=

The ESSCertID structure contains the SHA-1 hash of the whole certificate.
The Subject Key Identifier is any of:
The SHA-1 hash of the public key, as the content bytes of the SubjectPublicKeyInfo encoding.
ski = option_1[13..20]; ski[0] = 0x40 | (ski[0] & 0x0F)
The SHA-1 hash of the public key, as the fully encoded SubjectPublicKeyInfo
Anything else that the CA decides.
So there's not really a calculatable step to get from one to the other. Especially because of (4).
Certificate Transparency logs do help, though, since you can search them for certificates by many criteria. https://crt.sh/?q=5A25B4B5D82C19118C496917A4EA53309A859DDB (searching for the SHA-1 value from the ESSCertID) found the certificate, and its Subject Key Identifier is B7:44:AC:CA:A9:16:1F:D6:B7:F8:A1:00:49:D8:2E:BF:FE:5F:63:C8, which is the hex version of your base64 string.

Related

Decoding SCT extension in X.509 certificate

Im currently trying create some code to decode the SCT extension in a X.509 Certificate (OID: 1.3.6.1.4.1.11129.2.4.2). It has mostly been successful, however the SCT signature turns out wrong for me when comparing my result to OpenSSL. An example:
Mine:
37:F6:....:E2:16:....
OpenSSL:
30:45:02:20:37:F6:....:02:21:00:E2:16:....
To clarify the "...." are the same for both. For all my test cases, the same pattern of:
30:45:02:20 and 02:21:00 come up. When trying to interpret these additional octets my guess is that these represent: 0x30 -> SEQUENCE and 0x02 -> INTEGER and the following octets represents length etc. Should these be included in the signature or is there something i have missed?

Signature verification failure due to reordering via _asn1_ordering_set_of

I am using GnuTLS 3.4.1. I have a x509 certificate with set of sequences inside. The certificate is stored that way on a smart card.
GnuTLS is rearranging the sequences via function _asn1_ordering_set_of, which appears to be causing a verification failure.
Here's what the sequence looks like:
SEQUENCE :
...
SET :
SEQUENCE :
OBJECT_IDENTIFIER : 'CN (2.5.4.3)'
PrintableString : '0000'
SEQUENCE :
OBJECT_IDENTIFIER : 'SN (2.5.4.4)'
TeletexString : 'XXX'
SEQUENCE :
OBJECT_IDENTIFIER : 'G (2.5.4.42)'
TeletexString : 'YYY'
OpenSSL (and probably Java PKCS11 provider) loads this construction as is.
GnuTLS on load of the certificate sorts this construction in _asn1_ordering_set_of. So that it becomes:
SEQUENCE :
...
SET :
SEQUENCE :
OBJECT_IDENTIFIER : 'G (2.5.4.42)'
TeletexString : 'YYY'
SEQUENCE :
OBJECT_IDENTIFIER : 'SN (2.5.4.4)'
TeletexString : 'XXX'
SEQUENCE :
OBJECT_IDENTIFIER : 'CN (2.5.4.3)'
PrintableString : '0000'
Why does GnuTLS sort the set of sequences? What way should it be done, is it a GnuTLS bug or other libraries simply omit ordering?
RFC5280 has:
4.1. Basic Certificate Fields
The X.509 v3 certificate basic syntax is as follows. For signature
calculation, the data that is to be signed is encoded using the ASN.1
distinguished encoding rules (DER) [X.690].
So it seems to me that GnuTLS is doing the right thing.
It also looks like it's trying to encode a Distinguished Name, but does it wrong. It's valid according to the ASN1, because the spec is just really weird. You can have multiple values for each part. But you want the CN, SN and so on each in it's own SET, so all those SEQUENCEs should have had their own SET.
What way should it be done ...
The ITU recommends SET OF be encoded using BER, as long as there's no need for CER or DER. The best I can tell, there's no need. See below for a more detailed explanation in the realm of the ITU and ASN.1.
However, GnuTLS may be complying with a standard that creates the need. In this case, I'm not aware of which standard it is. See Kurt's answer.
I looked at RFC 5280, PKIX Certificate and CRL Profile, but I could not find the restriction. Maybe its in another PKIX document.
is it a GnuTLS bug or other libraries simply omit ordering?
I don't believe its a bug in GnuTLS per se. Its just the way the library does things. Take this modulo the requirement to do so in a RFC or other standard.
Also note that other libraries don't omit ordering. They use the order the attributes are presented in the certificate, which is an ordering :)
(comment) The problem is that GNUTLS rearranging results in failed SSL authentication
That sounds like a bug to me (modulo standards requirements). In this case, the bug is reordering the SET OF after a signature is placed upon the TBS/Certificate.
If GnuTLS is building the TBS/Certificate, then its OK to reorder until the signature is placed upon it.
(comment) Does GnuTLS put the elements of a SET OF type in the correct order according to DER rules
In ASN.1 encoding rules, X.690, BER/CER/DER:
8.12 Encoding of a set-of value
...
8.12.3 The order of data values need not be preserved by the encoding and subsequent decoding.
A SET OF does not appear to be ordered (for example, lexicographical order), so the sender can put them in any order, and a receiver can reorder them.
However, 11.6 says:
11 Restrictions on BER employed by both CER and DER
...
11.6 Set-of components
The encodings of the component values of a set-of value shall appear in ascending order, the encodings being compared as octet strings with the shorter components being padded at their trailing end with 0-octets.
NOTE – The padding octets are for comparison purposes only and do not appear in the encodings.
In the above, they are saying BER can be any order, but CER and DER are ascending order.
And last but not least, the Introduction says:
Introduction
...
... The basic encoding rules is more suitable than the canonical or distinguished encoding rules if the encoding contains a set value or set-of value and there is no need for the restrictions that the canonical and distinguished encoding rules impose ...
So the Introduction recommends BER for SET OF.
But in the big picture: the certificate is in BER. That's how it was signed. GnuTLS cannot change that once they get a hold of the certificate because of the signature over the certificate's data.
GnuTLS is free to create certificates in DER encoding. They just can't impose the encoding after the fact.
(comment) gnutls_certificate_set_x509_key_file(xcred, CERT_URL, KEY_URL, GNUTLS_X509_FMT_PEM);
I looked at the latest GnuTLS sources. That's appears to be the way its used in src/serv.c.
Apparently, _asn1_ordering_set_of was not working as expected in the past. It was improved in April, 2014. See PATCH 1/3: Make _asn1_ordering_set_of() really sort (and friends) on the GnuTLS mailing list.
Here are the hits for it in the sources:
$ grep -R -n _asn1_ordering_set_of * | grep -v doc
lib/minitasn1/coding.c:832: /* Function : _asn1_ordering_set_of */
lib/minitasn1/coding.c:843: _asn1_ordering_set_of (unsigned char *der, int der_len, asn1_node node)
lib/minitasn1/coding.c:1261: err = _asn1_ordering_set_of (der + len2, counter - len2, p);
The use around line 1261 is for asn1_der_coding. asn1_der_coding is used more frequently in other components...
(comment) but I'm not sure that it's bug in GNUTls and not on the server side, so I'd like to find out how it should work before doing anything
You should probably reach out ot the GnuTLS folks as detailed at B.3 Bug Reports. It looks like a bug in the processing of non-GnuTLS certificates.
To be clear, GnuTLS uses DER when it creates certificates and that's fine. But GnuTLS cannot impose ordering after it receives a non-GnuTLS certificate because that invalidates the signature.
Their test suite probably misses it because GnuTLS DER encodes SET OF. They likely are not aware its happening.

Decoding a coded variable

I use this function in order to encode an input:
Public Function encodeStrings(ByVal MyPass As String, ByVal MyUName As String) As String
Dim ENPass As String = Nothing
Dim password As String = (MyPass + MyUName)
Dim mhash As HashAlgorithm = New SHA1CryptoServiceProvider
Dim bytValue() As Byte = System.Text.Encoding.UTF8.GetBytes(password)
Dim bytHash() As Byte = mhash.ComputeHash(bytValue)
mhash.Clear()
ENPass = Convert.ToBase64String(bytHash)
Return ENPass
End Function
Now I need to decode this variable and get back the original string.
Does anyone know how to do that? I'm using VB.NET in my project.
No, there is no way to decode it. The SHA1CryptoServiceProvider implements a hashing algorithm. According to the MSDN:
Computes the SHA1 hash value for the input data...
SHA-1 is, by definition a hashing algorithm. According to the Wikipedia article:
In cryptography, SHA-1 is a cryptographic hash function designed by the United States National Security Agency and published by the United States NIST as a U.S. Federal Information Processing Standard. SHA-1 produces a 160-bit (20-byte) hash value. A SHA-1 hash value is typically expressed as a hexadecimal number, 40 digits long.
That is why it inherits from the HashAlgorithm base-class rather than the SymmetricAlgorithm base-class. Since it uses a hashing algorithm, that means that it is one-way encoded. The original string will always result in the same encrypted value, but there is no way to decrypt it to get back to the original value, since many different strings could result in that same encrypted value (although, with cryptographic hashing algorithms, such as SHA1, that is unfeasible).
If you think about it, that's the only thing that makes sense. If the SHA-1 algorithm always results in a hash code which is 20 bytes long, then that means you could encode a 1 gigabyte string and it would still only be 20 bytes long as an SHA-1 encrypted hash value. Surely you don't think that those 20 bytes contain all of the data that was originally stored in that 1 GB string. If that were the case, zipping files would be far more effective :)
Typically, when a cryptographic hashing algorithm is being used, it would be for something like storing a password. In that case, the issue is not how to decrypt the password, but rather, to encrypt the newly entered password and then compare the two encrypted values to see if they are the same. If the two encrypted values are the same, then you know that the user entered the right password. If the two encrypted values are not the same, then you know that it is incorrect (but you still don't know what the right password would be).
If you need a 2-way encryption algorithm, you need to use one which inherits from SymmetricAlgorithm, such as the AesCryptoServiceProvider class.

DSS, VRI - what is so mystructure?

I've just sign document using itext. I've LTV too.
I read in itext documentation - "The DSS contains references to certificates, and we can add
references to OCSP responses and CRLs that can be used to re-verify
the certificates"
yes, I fount them in my DSS.
I also read thet: "In the DSS, we can store VRI"
I dont understand why is VRI for? because there is the same OCSP responses and Certificates , which are in DSS.
Also wat does /61A2411B1..... means? is it some hash or Random number?
The structures you are interested in are defined in ETSI TS 102 778-4.
I dont understand why is VRI for? because there is the same OCSP responses and Certificates , which are in DSS.
While the Certs, OCSPs, and CRLs arrays in the DSS dictionary reference certificates, OCSP responses, and certificate revocation lists that may be used in the validation of any signatures in the document, the VRI dictionary contains Signature VRI dictionaries which reference the validation-related information for a single signature.
As your document contained but one signature, the information looks unnecessarily duplicated.
Also wat does /61A2411B1..... means? is it some hash or Random number?
The key of each entry in the VRI dictionary is the base-16-encoded (uppercase) SHA1 digest of the signature to which it applies.
PS: To clarify: key in the last sentence refers to the PDF structure: the VRI dictionary is a PDF dictionary in which a key (a PDF name object) is mapped to a value (another PDF object, in this case another PDF dictionary). It is not a cryptographic key from the signature...
Thus, you take the signature in question, calculate its SHA1 hash, write it in uppercase base-16-encoding, make that string as a PDF name, and then use that PDF name as PDF dictionary key.
Current latest ETSI specification is at https://www.etsi.org/deliver/etsi_en/319100_319199/31914201/01.01.01_60/en_31914201v010101p.pdf
You can leave the VRI out as its a duplicated data and actually not needed.
The VRI dictionary is optional, since all necessary data to validate
the signature can be available from other sources like the DSS
dictionary itself. The VRI dictionary offers possibilities for
optimization of the validation process, since it relates the data to
one specific signature.

ssh-2 rsa body format?

Is there any documentation on what the bignums in the body are?
Like here is an example pubkey.
ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIBMgigwcBaB3sqogC/yVPANQJKjMwOvrdOKhBIVlI2eOIq6FEyzNI8cbRDbHo5muipun922bLoV+p/dPZ2/8wJ+zugLM8eCdsr+VbYZ3T5wb7bjd2swePOWtffnsXnHiP8aWyRj64vd/mRPR1gYErg8vb7vM5c4B2ANKHs/rP65Bw== rsa-key-20100514
It contains 3 bignums with the sizes 7, 1, 128. Now I am assuming the 128 is the key while the 7 is the shared. But what about the other one? Also the privkey contains a lot more bignums which I have no idea what they are.
Edit:
So apparently what I am looking for is the format of the private key blob. I have searched and all I have found are references to the name and not the actual format.
The number with size 1 is the "version". What you observe is the encoding of a structure which contains the key elements. The structure follows ASN.1 conventions and encoding rules. In the case of RSA, the contents of the public and private keys are specified by PKCS#1 (see annex C for the ASN.1 specification, and section 3 for the human readable text).