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. > >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: int X509_digest(const X509 *data, const EVP_MD *type, unsigned char *md, unsigned int *len) { return(ASN1_item_digest(ASN1_ITEM_rptr(X509),type,(char *)data,md,len)); } 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 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)); this should place the requisite digest in mdbuf. Then ASN1_item_sign() needs to deal with padding, etc., which is signature algorithm dependent. > 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. 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; So all you need to figure out is how to set the sig_alg... -- Viktor. ______________________________________________________________________ OpenSSL Project http://www.openssl.org User Support Mailing List openssl-users@openssl.org Automated List Manager majord...@openssl.org