> From: owner-openssl-us...@openssl.org 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 openssl-users@openssl.org Automated List Manager majord...@openssl.org