Digitally Sign Document
francesco scalise
francescoscalise89 at gmail.com
Fri Sep 10 08:28:20 UTC 2021
Hi.
Briefly, my goal is to digitally sign a document using the API of the Cloud
Signature Consortium for the remote part and openssl for the local part.
First of alI I tried signing only locally, providing hard-coded certificate
and private key.
It works like a charm.
Here, the snippet I used for the purpose.
```
*static* *void* sign_with_signer( CustomSigner &signer, X509 *cert, EVP_PKEY
*pkey )
{
*[...]*
*int* rc;
BIO *mem = BIO_new( BIO_s_mem() );
*if*( !mem )
{
*[...]*
}
*unsigned* *int* flags = PKCS7_DETACHED | PKCS7_BINARY;
PKCS7 *pkcs7 = PKCS7_sign( cert, pkey, *NULL*, mem, flags );
*if*( !pkcs7 )
{
BIO_free( mem );
*[...]*
}
*while*( len = signer.ReadForSignature( pBuffer, uBufferLen ), len > 0 )
{
rc = BIO_write( mem, pBuffer, len );
*if*( *static_cast*<*unsigned* *int*>( rc ) != len )
{
PKCS7_free( pkcs7 );
BIO_free( mem );
*[...]*
}
}
* [...]*
*if*( PKCS7_final( pkcs7, mem, flags ) <= 0 )
{
PKCS7_free( pkcs7 );
BIO_free( mem );
*[...]*
}
*bool* success = *false*;
BIO *out = BIO_new( BIO_s_mem() );
*if*( !out )
{
PKCS7_free( pkcs7 );
BIO_free( mem );
*[...]*
}
*char* *outBuff = *NULL*;
*long* outLen;
i2d_PKCS7_bio( out, pkcs7 );
outLen = BIO_get_mem_data( out, &outBuff );
*if*( outLen > 0 && outBuff )
{
*if*( *static_cast*<size_t>( outLen ) > signer.GetSignatureSize() )
{
PKCS7_free( pkcs7 );
BIO_free( out );
BIO_free( mem );
*[...]*
}
Signature signature( outBuff, outLen );
signer.SetSignature( signature );
success = *true*;
}
PKCS7_free( pkcs7 );
BIO_free( out );
BIO_free( mem );
*if*( !success )
*[...]*
}
```
Now using the CSC `credentials/info` API I have:
```
"cert":
{
"status": "valid",
"certificates":
[
"<Base64-encoded_X.509_end_entity_certificate>",
"<Base64-encoded_X.509_intermediate_CA_certificate>",
"<Base64-encoded_X.509_root_CA_certificate>"
],
"issuerDN": "<X.500_issuer_DN_printable_string>", "serialNumber":
"5AAC41CD8FA22B953640", "subjectDN": "<X.500_subject_DN_printable_string>",
"validFrom": "20180101100000Z",
"validTo": "20190101095959Z"
},
```
So I have to build the X509 which I need to sign the document.
I guess using something like that:
```
*bool* pdf::CryptoModule::make_certificate(*const* *char* *data, X509
**out_cert)
{
*if*( !data || !*data )
{
*return* *false*;
}
*if*( !out_cert )
{
*return* *false*;
}
BIO *bio;
bio = BIO_new(BIO_s_mem());
BIO_puts(bio, data);
// *out_cert = PEM_read_bio_X509(bio, NULL, NULL, NULL);
*out_cert = d2i_X509_bio(bio, *NULL*);
*if*( !*out_cert )
{
*return* *false*;
}
*return* *true*;
}
```
But at this point I don't have the private key!
Instead, CSC `signatures/signHash` will provide me the signature object to
apply to the document.
```
{
"signatures":
[ "KedJuTob5gtvYx9qM3k3gm7kbLBwVbEQRl26S2tmXjqNND7MRGtoew==",
"Idhef7xzgtvYx9qM3k3gm7kbLBwVbE98239S2tm8hUh85KKsfdowel==" ]
}
```
Here is how things should work:
[image: page64image25534384]
At this point I would like to understand what are the openSSL APIs to use
for
- get the X509s
- get the raw signature of the document to be passed to the Signer who will
apply it.
In my humble opinion the
```
PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO **in*, *const* EVP_CIPHER
*cipher,
*int* flags);
*int* PKCS7_add_attrib_content_type(PKCS7_SIGNER_INFO *si, ASN1_OBJECT
*coid);
*int* PKCS7_add0_attrib_signing_time(PKCS7_SIGNER_INFO *si, ASN1_TIME *t);
*int* PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si,
*const* *unsigned* *char* *md, *int* mdlen);
```
could be what is right for me, but I'm not sure how to use it.
Thank you very much and have a nice day!
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mta.openssl.org/pipermail/openssl-users/attachments/20210910/5d64e346/attachment-0001.html>
More information about the openssl-users
mailing list