Encrypted Data type processing. Add options to cms utility and run section 7
tests in RFC4134.
This commit is contained in:
parent
5c4436c977
commit
b820455c6e
27
apps/cms.c
27
apps/cms.c
@ -86,6 +86,7 @@ static int smime_cb(int ok, X509_STORE_CTX *ctx);
|
|||||||
#define SMIME_DIGEST_CREATE (10 | SMIME_OP)
|
#define SMIME_DIGEST_CREATE (10 | SMIME_OP)
|
||||||
#define SMIME_UNCOMPRESS (11 | SMIME_IP)
|
#define SMIME_UNCOMPRESS (11 | SMIME_IP)
|
||||||
#define SMIME_COMPRESS (12 | SMIME_OP)
|
#define SMIME_COMPRESS (12 | SMIME_OP)
|
||||||
|
#define SMIME_ENCRYPTED_DECRYPT (13 | SMIME_IP)
|
||||||
|
|
||||||
int MAIN(int, char **);
|
int MAIN(int, char **);
|
||||||
|
|
||||||
@ -121,6 +122,8 @@ int MAIN(int argc, char **argv)
|
|||||||
#ifndef OPENSSL_NO_ENGINE
|
#ifndef OPENSSL_NO_ENGINE
|
||||||
char *engine=NULL;
|
char *engine=NULL;
|
||||||
#endif
|
#endif
|
||||||
|
unsigned char *secret_key = NULL;
|
||||||
|
size_t secret_keylen;
|
||||||
|
|
||||||
X509_VERIFY_PARAM *vpm = NULL;
|
X509_VERIFY_PARAM *vpm = NULL;
|
||||||
|
|
||||||
@ -164,6 +167,8 @@ int MAIN(int argc, char **argv)
|
|||||||
operation = SMIME_COMPRESS;
|
operation = SMIME_COMPRESS;
|
||||||
else if (!strcmp (*args, "-uncompress"))
|
else if (!strcmp (*args, "-uncompress"))
|
||||||
operation = SMIME_UNCOMPRESS;
|
operation = SMIME_UNCOMPRESS;
|
||||||
|
else if (!strcmp (*args, "-EncrypedData_decrypt"))
|
||||||
|
operation = SMIME_ENCRYPTED_DECRYPT;
|
||||||
#ifndef OPENSSL_NO_DES
|
#ifndef OPENSSL_NO_DES
|
||||||
else if (!strcmp (*args, "-des3"))
|
else if (!strcmp (*args, "-des3"))
|
||||||
cipher = EVP_des_ede3_cbc();
|
cipher = EVP_des_ede3_cbc();
|
||||||
@ -233,6 +238,20 @@ int MAIN(int argc, char **argv)
|
|||||||
flags |= CMS_NOOLDMIMETYPE;
|
flags |= CMS_NOOLDMIMETYPE;
|
||||||
else if (!strcmp (*args, "-crlfeol"))
|
else if (!strcmp (*args, "-crlfeol"))
|
||||||
flags |= CMS_CRLFEOL;
|
flags |= CMS_CRLFEOL;
|
||||||
|
else if (!strcmp(*args,"-secretkey"))
|
||||||
|
{
|
||||||
|
long ltmp;
|
||||||
|
if (!args[1])
|
||||||
|
goto argerr;
|
||||||
|
args++;
|
||||||
|
secret_key = string_to_hex(*args, <mp);
|
||||||
|
if (!secret_key)
|
||||||
|
{
|
||||||
|
BIO_printf(bio_err, "Invalid key %s\n", *args);
|
||||||
|
goto argerr;
|
||||||
|
}
|
||||||
|
secret_keylen = (size_t)ltmp;
|
||||||
|
}
|
||||||
else if (!strcmp(*args,"-rand"))
|
else if (!strcmp(*args,"-rand"))
|
||||||
{
|
{
|
||||||
if (!args[1])
|
if (!args[1])
|
||||||
@ -810,6 +829,12 @@ int MAIN(int argc, char **argv)
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (operation == SMIME_ENCRYPTED_DECRYPT)
|
||||||
|
{
|
||||||
|
if (!CMS_EncryptedData_decrypt(cms, secret_key, secret_keylen,
|
||||||
|
indata, out, flags))
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
else if (operation == SMIME_VERIFY)
|
else if (operation == SMIME_VERIFY)
|
||||||
{
|
{
|
||||||
if (CMS_verify(cms, other, store, indata, out, flags) > 0)
|
if (CMS_verify(cms, other, store, indata, out, flags) > 0)
|
||||||
@ -878,6 +903,8 @@ end:
|
|||||||
sk_free(sksigners);
|
sk_free(sksigners);
|
||||||
if (skkeys)
|
if (skkeys)
|
||||||
sk_free(skkeys);
|
sk_free(skkeys);
|
||||||
|
if (secret_key)
|
||||||
|
OPENSSL_free(secret_key);
|
||||||
X509_STORE_free(store);
|
X509_STORE_free(store);
|
||||||
X509_free(cert);
|
X509_free(cert);
|
||||||
X509_free(recip);
|
X509_free(recip);
|
||||||
|
@ -138,6 +138,13 @@ int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
|
|||||||
CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md,
|
CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md,
|
||||||
unsigned int flags);
|
unsigned int flags);
|
||||||
|
|
||||||
|
int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms,
|
||||||
|
const unsigned char *key, size_t keylen,
|
||||||
|
BIO *dcont, BIO *out, unsigned int flags);
|
||||||
|
|
||||||
|
int CMS_EncryptedData_set1_key(BIO *b, CMS_ContentInfo *cms,
|
||||||
|
const unsigned char *key, size_t keylen);
|
||||||
|
|
||||||
int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
|
int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
|
||||||
X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags);
|
X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags);
|
||||||
|
|
||||||
@ -255,6 +262,8 @@ void ERR_load_CMS_strings(void);
|
|||||||
#define CMS_F_CMS_DIGESTEDDATA_DO_FINAL 112
|
#define CMS_F_CMS_DIGESTEDDATA_DO_FINAL 112
|
||||||
#define CMS_F_CMS_DIGEST_VERIFY 113
|
#define CMS_F_CMS_DIGEST_VERIFY 113
|
||||||
#define CMS_F_CMS_ENCRYPTEDCONTENT_TO_BIO 138
|
#define CMS_F_CMS_ENCRYPTEDCONTENT_TO_BIO 138
|
||||||
|
#define CMS_F_CMS_ENCRYPTEDDATA_DECRYPT 140
|
||||||
|
#define CMS_F_CMS_ENCRYPTED_DATA_DECRYPT 139
|
||||||
#define CMS_F_CMS_ENVELOPED_DATA_INIT 114
|
#define CMS_F_CMS_ENVELOPED_DATA_INIT 114
|
||||||
#define CMS_F_CMS_FINAL 115
|
#define CMS_F_CMS_FINAL 115
|
||||||
#define CMS_F_CMS_GET0_CERTIFICATE_CHOICES 116
|
#define CMS_F_CMS_GET0_CERTIFICATE_CHOICES 116
|
||||||
@ -315,6 +324,7 @@ void ERR_load_CMS_strings(void);
|
|||||||
#define CMS_R_TYPE_NOT_COMPRESSED_DATA 128
|
#define CMS_R_TYPE_NOT_COMPRESSED_DATA 128
|
||||||
#define CMS_R_TYPE_NOT_DATA 129
|
#define CMS_R_TYPE_NOT_DATA 129
|
||||||
#define CMS_R_TYPE_NOT_DIGESTED_DATA 130
|
#define CMS_R_TYPE_NOT_DIGESTED_DATA 130
|
||||||
|
#define CMS_R_TYPE_NOT_ENCRYPTED_DATA 142
|
||||||
#define CMS_R_UNABLE_TO_FINALIZE_CONTEXT 131
|
#define CMS_R_UNABLE_TO_FINALIZE_CONTEXT 131
|
||||||
#define CMS_R_UNKNOWN_CIPHER 141
|
#define CMS_R_UNKNOWN_CIPHER 141
|
||||||
#define CMS_R_UNKNOWN_DIGEST_ALGORIHM 132
|
#define CMS_R_UNKNOWN_DIGEST_ALGORIHM 132
|
||||||
|
@ -132,18 +132,11 @@ int cms_bio_to_EncryptedContent(CMS_EncryptedContentInfo *ec,
|
|||||||
|
|
||||||
/* Return BIO based on EncryptedContentInfo and key */
|
/* Return BIO based on EncryptedContentInfo and key */
|
||||||
|
|
||||||
BIO *cms_EncryptedContent_to_bio(CMS_EncryptedContentInfo *ec,
|
int cms_EncryptedContent_to_bio(BIO *b, CMS_EncryptedContentInfo *ec,
|
||||||
const unsigned char *key, int keylen)
|
const unsigned char *key, int keylen)
|
||||||
{
|
{
|
||||||
BIO *b;
|
|
||||||
EVP_CIPHER_CTX *ctx;
|
EVP_CIPHER_CTX *ctx;
|
||||||
const EVP_CIPHER *ciph;
|
const EVP_CIPHER *ciph;
|
||||||
b = BIO_new(BIO_f_cipher());
|
|
||||||
if (!b)
|
|
||||||
{
|
|
||||||
CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_TO_BIO, ERR_R_MALLOC_FAILURE);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
BIO_get_cipher_ctx(b, &ctx);
|
BIO_get_cipher_ctx(b, &ctx);
|
||||||
|
|
||||||
ciph = EVP_get_cipherbyobj(ec->contentEncryptionAlgorithm->algorithm);
|
ciph = EVP_get_cipherbyobj(ec->contentEncryptionAlgorithm->algorithm);
|
||||||
@ -187,10 +180,18 @@ BIO *cms_EncryptedContent_to_bio(CMS_EncryptedContentInfo *ec,
|
|||||||
CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
|
CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
return b;
|
return 1;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
BIO_free(b);
|
return 0;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CMS_EncryptedData_set1_key(BIO *b, CMS_ContentInfo *cms,
|
||||||
|
const unsigned char *key, size_t keylen)
|
||||||
|
{
|
||||||
|
CMS_EncryptedContentInfo *ec;
|
||||||
|
if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_encrypted)
|
||||||
|
return 0;
|
||||||
|
ec = cms->d.encryptedData->encryptedContentInfo;
|
||||||
|
return cms_EncryptedContent_to_bio(b, ec, key, keylen);
|
||||||
|
}
|
||||||
|
@ -87,6 +87,8 @@ static ERR_STRING_DATA CMS_str_functs[]=
|
|||||||
{ERR_FUNC(CMS_F_CMS_DIGESTEDDATA_DO_FINAL), "CMS_DIGESTEDDATA_DO_FINAL"},
|
{ERR_FUNC(CMS_F_CMS_DIGESTEDDATA_DO_FINAL), "CMS_DIGESTEDDATA_DO_FINAL"},
|
||||||
{ERR_FUNC(CMS_F_CMS_DIGEST_VERIFY), "CMS_digest_verify"},
|
{ERR_FUNC(CMS_F_CMS_DIGEST_VERIFY), "CMS_digest_verify"},
|
||||||
{ERR_FUNC(CMS_F_CMS_ENCRYPTEDCONTENT_TO_BIO), "CMS_ENCRYPTEDCONTENT_TO_BIO"},
|
{ERR_FUNC(CMS_F_CMS_ENCRYPTEDCONTENT_TO_BIO), "CMS_ENCRYPTEDCONTENT_TO_BIO"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_ENCRYPTEDDATA_DECRYPT), "CMS_EncryptedData_decrypt"},
|
||||||
|
{ERR_FUNC(CMS_F_CMS_ENCRYPTED_DATA_DECRYPT), "CMS_ENCRYPTED_DATA_DECRYPT"},
|
||||||
{ERR_FUNC(CMS_F_CMS_ENVELOPED_DATA_INIT), "CMS_ENVELOPED_DATA_INIT"},
|
{ERR_FUNC(CMS_F_CMS_ENVELOPED_DATA_INIT), "CMS_ENVELOPED_DATA_INIT"},
|
||||||
{ERR_FUNC(CMS_F_CMS_FINAL), "CMS_final"},
|
{ERR_FUNC(CMS_F_CMS_FINAL), "CMS_final"},
|
||||||
{ERR_FUNC(CMS_F_CMS_GET0_CERTIFICATE_CHOICES), "CMS_GET0_CERTIFICATE_CHOICES"},
|
{ERR_FUNC(CMS_F_CMS_GET0_CERTIFICATE_CHOICES), "CMS_GET0_CERTIFICATE_CHOICES"},
|
||||||
@ -150,6 +152,7 @@ static ERR_STRING_DATA CMS_str_reasons[]=
|
|||||||
{ERR_REASON(CMS_R_TYPE_NOT_COMPRESSED_DATA),"type not compressed data"},
|
{ERR_REASON(CMS_R_TYPE_NOT_COMPRESSED_DATA),"type not compressed data"},
|
||||||
{ERR_REASON(CMS_R_TYPE_NOT_DATA) ,"type not data"},
|
{ERR_REASON(CMS_R_TYPE_NOT_DATA) ,"type not data"},
|
||||||
{ERR_REASON(CMS_R_TYPE_NOT_DIGESTED_DATA),"type not digested data"},
|
{ERR_REASON(CMS_R_TYPE_NOT_DIGESTED_DATA),"type not digested data"},
|
||||||
|
{ERR_REASON(CMS_R_TYPE_NOT_ENCRYPTED_DATA),"type not encrypted data"},
|
||||||
{ERR_REASON(CMS_R_UNABLE_TO_FINALIZE_CONTEXT),"unable to finalize context"},
|
{ERR_REASON(CMS_R_UNABLE_TO_FINALIZE_CONTEXT),"unable to finalize context"},
|
||||||
{ERR_REASON(CMS_R_UNKNOWN_CIPHER) ,"unknown cipher"},
|
{ERR_REASON(CMS_R_UNKNOWN_CIPHER) ,"unknown cipher"},
|
||||||
{ERR_REASON(CMS_R_UNKNOWN_DIGEST_ALGORIHM),"unknown digest algorihm"},
|
{ERR_REASON(CMS_R_UNKNOWN_DIGEST_ALGORIHM),"unknown digest algorihm"},
|
||||||
|
@ -411,6 +411,12 @@ void cms_DigestAlgorithm_set(X509_ALGOR *alg, const EVP_MD *md);
|
|||||||
BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm);
|
BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm);
|
||||||
int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain,
|
int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain,
|
||||||
X509_ALGOR *mdalg);
|
X509_ALGOR *mdalg);
|
||||||
|
|
||||||
|
int cms_bio_to_EncryptedContent(CMS_EncryptedContentInfo *ec,
|
||||||
|
const unsigned char *key, int keylen,
|
||||||
|
BIO *b);
|
||||||
|
int cms_EncryptedContent_to_bio(BIO *b, CMS_EncryptedContentInfo *ec,
|
||||||
|
const unsigned char *key, int keylen);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -139,6 +139,10 @@ BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont)
|
|||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
case NID_pkcs7_encrypted:
|
||||||
|
cmsbio = BIO_new(BIO_f_cipher());
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
CMSerr(CMS_F_CMS_DATAINIT, CMS_R_UNSUPPORTED_TYPE);
|
CMSerr(CMS_F_CMS_DATAINIT, CMS_R_UNSUPPORTED_TYPE);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -152,7 +156,7 @@ BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int CMS_dataFinal(CMS_ContentInfo *cms, BIO *cmsbio)
|
int CMS_dataFinal(CMS_ContentInfo *cms, BIO *cmsbio)
|
||||||
{
|
{
|
||||||
ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
|
ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
|
||||||
|
@ -188,6 +188,40 @@ CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms,
|
||||||
|
const unsigned char *key, size_t keylen,
|
||||||
|
BIO *dcont, BIO *out, unsigned int flags)
|
||||||
|
{
|
||||||
|
BIO *cont;
|
||||||
|
int r;
|
||||||
|
if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_encrypted)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_ENCRYPTEDDATA_DECRYPT,
|
||||||
|
CMS_R_TYPE_NOT_ENCRYPTED_DATA);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dcont)
|
||||||
|
{
|
||||||
|
ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
|
||||||
|
if (!pos || !*pos)
|
||||||
|
{
|
||||||
|
CMSerr(CMS_F_CMS_ENCRYPTEDDATA_DECRYPT,
|
||||||
|
CMS_R_NO_CONTENT);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cont = CMS_dataInit(cms, dcont);
|
||||||
|
if (!cont)
|
||||||
|
return 0;
|
||||||
|
r = CMS_EncryptedData_set1_key(cont, cms, key, keylen);
|
||||||
|
if (r)
|
||||||
|
r = cms_copy_content(out, cont, flags);
|
||||||
|
BIO_free_all(cont);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
static int cms_signerinfo_verify_cert(CMS_SignerInfo *si,
|
static int cms_signerinfo_verify_cert(CMS_SignerInfo *si,
|
||||||
X509_STORE *store,
|
X509_STORE *store,
|
||||||
STACK_OF(X509) *certs,
|
STACK_OF(X509) *certs,
|
||||||
|
@ -77,10 +77,12 @@ my @test_list = (
|
|||||||
["5.1.bin" => "encode"],
|
["5.1.bin" => "encode"],
|
||||||
["5.2.bin" => "encode"],
|
["5.2.bin" => "encode"],
|
||||||
["6.0.bin" => "encode, digest, cont"],
|
["6.0.bin" => "encode, digest, cont"],
|
||||||
["7.1.bin" => "encode"],
|
["7.1.bin" => "encode, encrypted, cont"],
|
||||||
["7.2.bin" => "encode"]
|
["7.2.bin" => "encode, encrypted, cont"]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
my $secretkey = "73:7c:79:1f:25:ea:d0:e0:46:29:25:43:52:f7:dc:62:91:e5:cb:26:91:7a:da:32";
|
||||||
|
|
||||||
if (!-d $exdir)
|
if (!-d $exdir)
|
||||||
{
|
{
|
||||||
print STDERR "FATAL ERROR: examples directory missing!!\n";
|
print STDERR "FATAL ERROR: examples directory missing!!\n";
|
||||||
@ -111,6 +113,10 @@ foreach (@test_list) {
|
|||||||
{
|
{
|
||||||
run_digest_test($exdir, $tlist, $file);
|
run_digest_test($exdir, $tlist, $file);
|
||||||
}
|
}
|
||||||
|
if ($tlist =~ /encrypted/)
|
||||||
|
{
|
||||||
|
run_encrypted_test($exdir, $tlist, $file, $secretkey);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,6 +240,32 @@ sub run_digest_test
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub run_encrypted_test
|
||||||
|
{
|
||||||
|
my ($cmsdir, $tlist, $tfile, $key) = @_;
|
||||||
|
unlink "tmp.txt";
|
||||||
|
|
||||||
|
system ("$cmscmd -EncrypedData_decrypt -inform DER" .
|
||||||
|
" -secretkey $key" .
|
||||||
|
" -in $cmsdir/$tfile -out tmp.txt");
|
||||||
|
|
||||||
|
if ($?)
|
||||||
|
{
|
||||||
|
print "\tEncrypted Data command FAILED!!\n";
|
||||||
|
$badtest++;
|
||||||
|
}
|
||||||
|
elsif ($tlist =~ /cont/ &&
|
||||||
|
!cmp_files("$cmsdir/ExContent.bin", "tmp.txt"))
|
||||||
|
{
|
||||||
|
print "\tEncrypted Data content compare FAILED!!\n";
|
||||||
|
$badtest++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
print "\tEncryptedData verify passed\n" if $verbose;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sub cmp_files
|
sub cmp_files
|
||||||
{
|
{
|
||||||
my ($f1, $f2) = @_;
|
my ($f1, $f2) = @_;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user