Как создать подписанное сообщение DER CMS и проверить его с помощью библиотеки openssl? - PullRequest
0 голосов
/ 10 июня 2019

Я создал частный сертификат и успешно сгенерировал и проверил подписанные данные CMS с помощью команды OpenSSL.

$ openssl cms -sign -signer server.pem -inkey server.key -nodetach -md sha256 -in LLS_SignedMultiTable_SignedArea.bin -outform der -out sample.cms-der -noattr
$ openssl cms -verify -CAfile root.crt.pem -inform der -in sample.cms-der 

Я хочу создать свою собственную утилиту для «подписи» и «проверки» с использованием языка C и OpenSSLбиблиотека.Кроме того, я хочу убедиться, что подписанные данные CMS имеют «sha256WithRSAEncryption» вместо «rsaEncryption».

$ openssl asn1parse -inform der -in ./sample.cms-der  

  193:d=10 hl=2 l=   9 prim: OBJECT            :rsaEncryption
  204:d=10 hl=2 l=   0 prim: NULL
  206:d=6  hl=2 l=  47 cons: SEQUENCE
  208:d=7  hl=2 l=   9 prim: OBJECT            :messageDigest
  219:d=7  hl=2 l=  34 cons: SET
  221:d=8  hl=2 l=  32 prim: OCTET STRING      [HEX DUMP]: ....
  255:d=5  hl=2 l=  13 cons: SEQUENCE
  257:d=6  hl=2 l=   9 prim: OBJECT            :rsaEncryption
  268:d=6  hl=2 l=   0 prim: NULL
  270:d=5  hl=4 l= 256 prim: OCTET STRING      [HEX DUMP]: ....

Вот мой исходный код.Он создал данные в формате DER, подписанные, но проверить не удалосьИ его подписанные данные сгенерировали rsaEncryption, а не sha256WithRSAEncryption.

Как я могу создать подписанные CMS данные sha256WithRSAEncryption и проверить их?

$ cat cms_sign.c
/* Simple S/MIME signing example */
#include <openssl/pem.h>
#include <openssl/cms.h>
#include <openssl/err.h>

int main(int argc, char **argv)
{
    BIO *in = NULL, *out = NULL, *tbio = NULL;
    X509 *scert = NULL;
    EVP_PKEY *skey = NULL;
    CMS_ContentInfo *cms = NULL;
    int ret = 1;



int flags = CMS_DETACHED | CMS_NOINTERN | CMS_NOINTERN |CMS_BINARY ;

OpenSSL_add_all_algorithms();
ERR_load_crypto_strings();

/* Read in signer certificate and private key */
tbio = BIO_new_file(argv[1], "r");

if (!tbio)
    goto err;

scert = PEM_read_bio_X509(tbio, NULL, 0, NULL);

BIO_reset(tbio);

skey = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL);

if (!scert || !skey)
    goto err;

/* Open content being signed */

in = BIO_new_file(argv[2], "r");

if (!in)
    goto err;

/* Sign content */
cms = CMS_sign(scert, skey, NULL, in, flags);

if (!cms)
    goto err;

out = BIO_new_file("sample.cms-der", "w");
if (!out)
    goto err;

if ( !i2d_CMS_bio(out, cms))
    goto err;

ret = 0;

 err:

    if (ret) {
        fprintf(stderr, "Error Signing Data\n");
        ERR_print_errors_fp(stderr);
    }

    CMS_ContentInfo_free(cms);
    X509_free(scert);
    EVP_PKEY_free(skey);
    BIO_free(in);
    BIO_free(out);
    BIO_free(tbio);
    return ret;
}

$ cat cms_verify.c
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>              /* open() */

#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/ssl.h>
#include <openssl/pkcs7.h>
#include <openssl/safestack.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>     /* X509_PURPOSE_ANY */
#include <openssl/x509_vfy.h>

#include <openssl/cms.h>
#include <openssl/pem.h>


int testcms (const char* cert_path, const char* sod_path)
{
    BIO *in = NULL, *out = NULL, *tbio = NULL, *cont = NULL;
    X509_STORE *st = NULL;
    X509 *cacert = NULL;
    CMS_ContentInfo *cms = NULL;

    int ret = 1;

    OpenSSL_add_all_algorithms();
    ERR_load_crypto_strings();

    st = X509_STORE_new();

    tbio = BIO_new_file(cert_path, "r");

    if (!tbio) {
        fprintf(stderr, "Cert file not opened: path=%s;\n", cert_path);
        goto err;
    }

    cacert = PEM_read_bio_X509(tbio, NULL, 0, NULL);

    if (!cacert) {
        fprintf(stderr, "PEM_read_bio_X509 FAILED: cert.path=%s;\n", 
   cert_path);
        goto err;
    }

    if (!X509_STORE_add_cert(st, cacert)) {
        fprintf(stderr, "X509_STORE_add_cert FAILED: cert.path=%s;\n", 
        cert_path);
        goto err;
    }

    in = BIO_new_file(sod_path, "r");

    if (!in) {
        fprintf(stderr, "PKCS7 file not opened: path=%s;\n", sod_path);
        goto err;
    }


cms = d2i_CMS_bio(in, NULL);

if (!cms) {
    fprintf(stderr, "SMIME_read_CMS FAILED: pkcs7.path=%s;\n", sod_path);
    goto err;
}

 out = BIO_new_file("smver.txt", "w");
if (!out)
    goto err;

if (!CMS_verify(cms, NULL, st, cont, out, 0)) {
    fprintf(stderr, "Verification Failure\n");
    goto err;
}

fprintf(stderr, "Verification Successful\n");

ret = 0;

err:

if (ret) {
    fprintf(stderr, "Error Verifying Data\n");
    ERR_print_errors_fp(stderr);
}

    CMS_ContentInfo_free(cms);
    X509_free(cacert);
    BIO_free(in);
    BIO_free(out);
    BIO_free(tbio);
    return ret;
}

void usage ()
{
  printf("program cert_path signature_path\n");
}

int main (int argc, char *argv[])
{

  if (argc < 2 ) { usage(); return 0; }
  testcms(argv[1], argv[2]);
  return 0;
}
...