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 )
[...]
}
"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"
},
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;
}
{
"signatures":
[ "KedJuTob5gtvYx9qM3k3gm7kbLBwVbEQRl26S2tmXjqNND7MRGtoew==",
"Idhef7xzgtvYx9qM3k3gm7kbLBwVbE98239S2tm8hUh85KKsfdowel==" ]
}
- get the X509s
- get the raw signature of the document to be passed to the Signer who will apply it.
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);