PKCS7 messages

From OpenCA::Wiki

Loading a PKCS#7 Message

This example shows how to load a PKCS#7 file and get the embedded data from the file:

  #include <libpki/pki.h>
  
  int main () {
  
       PKI_X509_PKCS7 *p7 = NULL;
       BIO *p7bio = NULL;
       PKI_X509_CERT_STACK *sk_cert = NULL;
       PKI_MEM * mem = NULL;
  
       PKI_init_all();
       // Loads the PKCS7 file ("data.der")
       if((p7 = PKI_X509_PKCS7_get ( "data.der", NULL, NULL )) == NULL ) {
               exit(1);
       }
       // Gets the data from a PKCS7 object
       if((mem = PKI_X509_PKCS7_get_data( p7, NULL, NULL )) == NULL ) {
               printf("ERROR: Can not get data!\n");
               exit(1);
       }
       // Naively prints out the data from the PKI_MEM data structure
       printf("DATA:\n%s\n", mem->data);
       // Saves the file in PEM format
       PKI_X509_PKCS7_put ( p7, PKI_DATA_FORMAT_PEM,
                       "output/p7.pem", NULL, NULL, NULL );
  
       return 0;
  }

Create a new PKCS7

This example shows how to create a new PKCS7 and encrypt its contents for a recipient (cacert.pem)

 #include <libpki/pki.h>
 
 int main () {
 
       PKI_MSG_REQ *r = NULL;
       PKI_X509_CERT *cacert = NULL;
       PKI_TOKEN *tk = NULL;
       PKI_MEM_STACK *mem_sk = NULL;
       PKI_X509_PKCS7 *p7 = NULL;
       BIO *p7bio = NULL;
       PKI_MEM *mm = NULL;
  
       // This is the data to be transmitted
       char *data = "aaaaaaaaaaaaaaaaavvvvvvvvvvvvvvbbbbbbbbbbbbb";
  
       PKI_init_all();
  
       // Load the cacert.pem certificate  
       if((cacert = PKI_X509_CERT_get( "cacert.pem", NULL, NULL )) == NULL ){
               printf("ERROR, can not load cacert.pem!\n\n");
               exit(1);
       }
  
       // We need a new PKI_TOKEN to sign with - let's create a new one,
       // a new keypair, and a self-signed certificate
       if((tk = PKI_TOKEN_new_null()) == NULL ) {
               printf("ERROR, can not create a new token!\n");
               exit ( 1 );
       }
       if((PKI_TOKEN_new_keypair(tk, 1024, NULL)) == PKI_ERR){
               printf("ERROR, can not generate new keypair!\n");
               exit(1);
       }
       PKI_TOKEN_set_cacert( tk, cacert );
  
       /* We need a signer to sign the P7! */
       PKI_TOKEN_new_req ( tk, "CN=Max2, O=OpenCA", NULL );
       PKI_TOKEN_self_sign( tk, NULL, NULL, 3600*24*30, NULL );
  
       // Let's create a new PKCS7 (signed and encrypted)
       if((p7 = PKI_X509_PKCS7_new( PKI_X509_PKCS7_TYPE_SIGNEDANDENCRYPTED )) == NULL ) {
               printf("ERROR, can not gen new PKCS7\n");
               exit(1);
       }
       // Now we add the recipient (in this case, the newly created certificate)
       PKI_X509_PKCS7_add_recipient ( p7, tk->cert );
       // Here we add the signer information from the PKI_TOKEN
       PKI_X509_PKCS7_add_signer_tk ( p7, tk, NULL );
       // All we need to do now is to "encode" the data we want to encode in the
       // final PKCS7 file
       if(PKI_X509_PKCS7_encode(p7, data, strlen(data)+1 ) == PKI_ERR) {
               printf("ERROR!!!!\n\n");
               exit(1);
       }
       // Now we save the new PKCS#7 file
       PKI_X509_PKCS7_put( p7, PKI_DATA_FORMAT_PEM, "output/p7_enc.pem", NULL, NULL, NULL );
 
       // As a test, we decrypt the new PKCS7 data by using our certificate
       if((mm = PKI_X509_PKCS7_get_data( p7, tk->keypair, tk->cert)) == NULL ){
               printf("ERROR::Can not decrypt!\n");
       } else {
               printf("DATA %d \n => %s <== END\n\n", mm->size, mm->data );
       }
   
       return 0;
  }


Adding Signed Attributes

This example shows how to add a signed attribute to a PKCS#7 object. For simplicity, we assume a p7 has already been created. We omit the PKI_TOKEN creation/load part.


  #include <libpki/pki.h>
  
  int main () {
  
       PKI_X509_CERT *cacert = NULL;
       PKI_TOKEN *tk = NULL;
       PKI_MEM_STACK *mem_sk = NULL;
       PKI_X509_PKCS7 *p7 = NULL;
       PKI_X509_CERT_STACK *sk_cert = NULL;
       PKI_X509_ATTRIBUTE *attr = NULL;
       PKI_X509_CRL * crl = NULL;
 
       char *data = "THIS IS THE DATA!";
  
       ....
  
       // Here we create the new Attribute
       attr = PKI_X509_ATTRIBUTE_new (
                       PKI_X509_SCEP_ATTRIBUTE_get_nid (
                               SCEP_ATTRIBUTE_MESSAGE_TYPE),
               V_ASN1_PRINTABLESTRING, "Pippo", 6);
  
       // Check for errors
       if( attr == NULL ) {
               printf("ERROR::Can not create Attribute!\n\n");
               exit ( 1 );
       } else {
               int i = 0;
               // Adds the signed attribute
               i = PKI_X509_PKCS7_add_signed_attribute( p7, attr );
               printf("ADDED SIGNED ATTRIBUTE => RESULT is %d\n", i );
       }
  
       // Why not adding a CRL to the PKCS7 ?
       crl = PKI_X509_CRL_get ( "crl.pem", NULL, NULL );
       PKI_X509_PKCS7_add_crl ( p7, crl );
  
       // When ready, we finalize the data structure by encoding it
       if( PKI_X509_PKCS7_encode( p7, data, strlen(data)+1 ) == PKI_ERR){
               printf("ERROR::Can not Sign!!!!\n\n");
       }
 
       // Let's save the PKCS7 in B64
       PKI_X509_PKCS7_put ( p7, PKI_DATA_FORMAT_B64,
                       "output/test_6_p7.b64", NULL, NULL, NULL );
   
       return 0;
   }