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 [email protected]
Automated List Manager [email protected]