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