>From: owner-openssl-users On Behalf Of Dereck Hurtubise
>Sent: Wednesday, November 27, 2013 04:40

>I'm trying to verify an x509 certificate with a custom library (other than
openssl)
>The reason I'm writing to this mailing list is that I can't figure out what
is going wrong.
>The certificate is created on a server by openssl with RSA/SHA1, or some
other algorithm.
>The modulus is 1024 bit and the e-bits are 3.
>The algorithm used to create the signature, is that RSA/SHA1 with PKCS1
v1.5?

By default yes, and confirmed by this OID:

>The OID I'm getting is: 1.2.840.113549.1.1.5
>The NID given, according to NTP, is 65.

>The functions called to create this certificate, used by ntp-keygen, are
these:
>- Create RSA key-pair
>   - RSA_generate_key(1024, 3, cb, "RSA");
 >      - So the modulus is 1024 bits, the exponent is 3, cb is some
callback function,
 >        and "RSA" is what?

A pointer to a structure (RSA is declared as a typedef for struct rsa_st in
openssl/rsa.h)
where the generated key is placed. In the same way the cert structure used
below 
is a pointer to X509 which is a typedef for struct x509_st.

>   - RSA_check_key(rsa)
>      - This checks the rsa key generated for validity, right?

Yes, although that's not necessary here.

>- Create certificate
>    - The certificate is filled with all the necessary info
>    - The public key is set: X509_set_pubkey(cert, pkey)
>         - cert is the internal openssl certificate format. 
>         - pkey is the key pair in the openssl internal format.
>    - The CA is set to TRUE, along with some other extensions for key
constraints etc.
>    - The certificate is signed: X509_sign(cert, pkey, md)
>        - md is the message digest algorithm to use, which is the NID of
RSA/SHA1 (65 correct?)
>    - The certificate is verified using: X509_verify(cert, pkey)

>Then the certificate is transmitted from this server in DER format 
>(converted from the internal openssl format to DER with the i2d routine in
openssl)
>This DER format is what I'm getting. The certificate is read correctly.
>The only thing I can't figure out is how this certificate's signature
should be verified.

>The certificate being verified is self-signed and created in the above
manner.
>So the issuer and subject are the same and the extension CA is TRUE.
>Also, there is an extension called trustRoot.

To be exact the >BasicConstraints< extension contains the field CA = TRUE.
(It can contain another field as well, but in this case doesn't.)
Similarly TrustRoot is the (only) value in >ExtendedKeyUsage<.

>So the main questions are these:
>- How should the RSA key format be interpreted?
>   - The modulus is easy
>   - Is the exponent transmitted the e-bits portion of the RSA format?
>       - If so, how does this translate to the exponent portion?
>         If the e-bits are 3, does this mean the exponent is (2^(e-bits
-1)) + 1?
>         So, in the example: 2^2 + 1 = 5?
>       - If not, then what?

The RSA key in (the bit string in) subjectPublicKeyInfo is encoded per 
PKCS#1 which is now RFC 3447. It is an ASN.1 (DER) SEQUENCE of 
two INTEGERs, the modulus n and the public exponent e. For the 
generate call above the exponent is 3. Not 3 bits, the number 3.
But you should use or at least compare the value in the key, so
you don't go off the rails if it is changed in the future.

>- How do I verify the signature?
>   - Is the algorithm to verify with RSA/SHA1 with PKCS1 v1.5?
>   - Is the signature wrapped in any way and with which scheme if so?

Yes. The signature and verification scheme is also defined by PKCS#1.
(There are actually two schemes, v1_5 and PSS, but the openssl default,
everyone else's default I've seen, and the OID in the cert all say v1_5.
In brief: hash the TBS (see next), encode hash with an algorithmidentifier 
(which amounts to adding a fixed prefix, see PKCS#1), pad with 00 01 
a bunch of FFs and 00, and compute ^d mod n (often imprecisely called
'encrypt with private key', and usually done by the more complicated 
but more efficient CRT algorithm).

>   - Do I use the DER data up to and excluding the signature portion?
>   - If any data of the DER format needs to be excluded from the hash,
which data?

The "to be signed" or "TBS" is the first component in the outer SEQUENCE. 
I.e. the cert is SEQUENCE { cert_info SEQUENCE { ... good stuff ... },
algid AlgorithmIdentifier, sigval BIT STRING }. sigval is the signature 
using the algorithm specified by algid on the DER value of cert_info.
(This SEQUENCE{TBS,algid,sigval} pattern applies other places as well.)

>Any help would be great and much appreciated.

Note that verifying the signature on a self-signed cert is nearly useless;
it only tells you the cert wasn't corrupted in transmission, or your
storage.
It does NOT provide any evidence at all that the server you got it from,
or the server identified in it, is legitimate in any way whatsoever.
If you got it from a legitimate source or authority by a means which 
prevents substitution, then you can trust it without verification.
If you didn't, you can't trust if, verification or no.

What you can do with a root or other self-signed cert is verify something 
*else*. In your case, I presume messages from the NTP server.


______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           majord...@openssl.org

Reply via email to