> From: [email protected] On Behalf Of Viktor Dukhovni
> Sent: Friday, 10 May, 2013 12:20
> On Fri, May 10, 2013 at 11:26:35AM -0400, Ken Goldman wrote:
>
> > >a) get the der encoded value of tbsCertificate field
> > >b) hash it
> > >c) apply pkcs1 padding and sign it
> > >d) put the signature on asn1 form
> > >e) add NIDs and other parameters to the cert_info field
> you identified.
The 'signature' (really X509_ALGOR aka AlgorithmIdentifier)
*within* cert_info (which is tbsCertificate) must be set
before 'a' is done. It contains one OID (typically but not
necessarily derived from NID) and syntactically can contain
parameters but I don't see why it ever would. (AlgId for a key
does depending on alg, AlgId for using a key doesn't need to.)
After 'd' combine cert_info-aka-TBS + (copy of) AlgId + signature
(in BITSTRING). (More below.)
> > >I spent a lot of time learning from forums and openssl code
> > >(X509_REQ_sign and functions it calls in my case) what I
> need to do. If
> > >you can, go for option 1). If nto I may help you more later with 2)
> >
> > Yes, your flow is the same as mine. I'm looking for advice on the C
> > function calls. Specifically,
> >
> > Is X509_digest() useful for a) and b)?
>
> No. It is used to obtained digests of fully-formed certificates,
> including the existing signature, when signing a certificate,
> one signs only the parts that exclude the signature algorithm
> information and the signature bits.
>
> If you look at X509_digest() it is a simple wrapper around
> ASN1_item_digest: <snip>
Right. The hash of the complete cert is often used as a
"fingerprint" for display to a human, as a (overwhelmingly)
unique and quickly distinguishable identifier of a cert.
> If you look at X509_sign(), it wraps ASN1_item_sign():
>
> int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md)
> {
> x->cert_info->enc.modified = 1;
> return(ASN1_item_sign(ASN1_ITEM_rptr(X509_CINF),
> x->cert_info->signature, x->sig_alg,
> x->signature, x->cert_info,pkey,md));
> }
>
> The thing to notice is that ASN.1 representation structure in
> the second
> case is for X509_CINF, not X509. The former excludes the
> signature part
and the data encoded (as X509_CINF) is x->cert_info.
> of the certificate. So my guess for exctracting a signature
> to be signed
> is that you want:
>
> X509 *cert;
> EVP_MD *mdalg = EVP_get_digestbyname("sha1"); /* or whatever */
> unsigned char mdbuf[EVP_MAX_MD_SIZE];
> unsigned int mdlen;
>
> cert = ...;
> ASN1_item_digest(ASN1_ITEM_rptr(X509_CINF), mdalg, cert,
> mdbuf, &mdlen));
>
Data should be cert->cert_info as above.
> this should place the requisite digest in mdbuf. Then
> ASN1_item_sign()
> needs to deal with padding, etc., which is signature
> algorithm dependent.
>
It lets EVP_DigestSign* deal with padding and signing algorithm.
OP needs an equivalent using his HSM.
> > Is there a high level call for d) and e) or must I do it using the
> > ASN.1 API?
>
> An in memory X509 certificate is:
>
> struct x509_st {
> X509_CINF *cert_info;
> X509_ALGOR *sig_alg;
> ASN1_BIT_STRING *signature;
> ...
> }
>
> Just update the sig_alg and signature freeing old values and
> replacing with new and set x->cert_info->enc.modified = 1.
>
If there are old values; it sounded to me like OP was constructing
a new cert from scratch. In that case I think you also don't need
enc.modified, but maybe better safe than sorry.
> The signature update code in ASN1_item_sign_ctx looks like:
>
> if (signature->data != NULL)
> OPENSSL_free(signature->data);
> signature->data = mdbuf;
> signature->length = mdlen;
> /* Make sure that the bit string has a 'not-used
> bits' value of 0 */
> signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
> signature->flags |= ASN1_STRING_FLAG_BITS_LEFT;
>
Almost, but you've mixed tabs and spaces in a way that makes
the indentation misleading.
> So all you need to figure out is how to set the sig_alg...
As above all you really need is the OID; _item_sign_ctx shows
how to do the parameter but in practice it's NULL or omitted.
______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List [email protected]
Automated List Manager [email protected]