Latest update

This commit is contained in:
2019-07-13 19:13:22 +09:00
parent 9a23f88dc2
commit 2e57f602ae
542 changed files with 17287 additions and 6184 deletions
+133 -1
View File
@@ -13,6 +13,56 @@
#include <openssl/err.h>
#include <openssl/cms.h>
#include "cms_lcl.h"
#include "internal/nelem.h"
/*-
* Attribute flags.
* CMS attribute restrictions are discussed in
* - RFC 5652 Section 11.
* ESS attribute restrictions are discussed in
* - RFC 2634 Section 1.3.4 AND
* - RFC 5035 Section 5.4
*/
/* This is a signed attribute */
#define CMS_ATTR_F_SIGNED 0x01
/* This is an unsigned attribute */
#define CMS_ATTR_F_UNSIGNED 0x02
/* Must be present if there are any other attributes of the same type */
#define CMS_ATTR_F_REQUIRED_COND 0x10
/* There can only be one instance of this attribute */
#define CMS_ATTR_F_ONLY_ONE 0x20
/* The Attribute's value must have exactly one entry */
#define CMS_ATTR_F_ONE_ATTR_VALUE 0x40
/* Attributes rules for different attributes */
static const struct {
int nid; /* The attribute id */
int flags;
} cms_attribute_properties[] = {
/* See RFC Section 11 */
{ NID_pkcs9_contentType, CMS_ATTR_F_SIGNED
| CMS_ATTR_F_ONLY_ONE
| CMS_ATTR_F_ONE_ATTR_VALUE
| CMS_ATTR_F_REQUIRED_COND },
{ NID_pkcs9_messageDigest, CMS_ATTR_F_SIGNED
| CMS_ATTR_F_ONLY_ONE
| CMS_ATTR_F_ONE_ATTR_VALUE
| CMS_ATTR_F_REQUIRED_COND },
{ NID_pkcs9_signingTime, CMS_ATTR_F_SIGNED
| CMS_ATTR_F_ONLY_ONE
| CMS_ATTR_F_ONE_ATTR_VALUE },
{ NID_pkcs9_countersignature, CMS_ATTR_F_UNSIGNED },
/* ESS */
{ NID_id_smime_aa_signingCertificate, CMS_ATTR_F_SIGNED
| CMS_ATTR_F_ONLY_ONE
| CMS_ATTR_F_ONE_ATTR_VALUE },
{ NID_id_smime_aa_signingCertificateV2, CMS_ATTR_F_SIGNED
| CMS_ATTR_F_ONLY_ONE
| CMS_ATTR_F_ONE_ATTR_VALUE },
{ NID_id_smime_aa_receiptRequest, CMS_ATTR_F_SIGNED
| CMS_ATTR_F_ONLY_ONE
| CMS_ATTR_F_ONE_ATTR_VALUE }
};
/* CMS SignedData Attribute utilities */
@@ -149,4 +199,86 @@ void *CMS_unsigned_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid,
return X509at_get0_data_by_OBJ(si->unsignedAttrs, oid, lastpos, type);
}
/* Specific attribute cases */
/*
* Retrieve an attribute by nid from a stack of attributes starting at index
* *lastpos + 1.
* Returns the attribute or NULL if there is no attribute.
* If an attribute was found *lastpos returns the index of the found attribute.
*/
static X509_ATTRIBUTE *cms_attrib_get(int nid,
const STACK_OF(X509_ATTRIBUTE) *attrs,
int *lastpos)
{
X509_ATTRIBUTE *at;
int loc;
loc = X509at_get_attr_by_NID(attrs, nid, *lastpos);
if (loc < 0)
return NULL;
at = X509at_get_attr(attrs, loc);
*lastpos = loc;
return at;
}
static int cms_check_attribute(int nid, int flags, int type,
const STACK_OF(X509_ATTRIBUTE) *attrs,
int have_attrs)
{
int lastpos = -1;
X509_ATTRIBUTE *at = cms_attrib_get(nid, attrs, &lastpos);
if (at != NULL) {
int count = X509_ATTRIBUTE_count(at);
/* Is this attribute allowed? */
if (((flags & type) == 0)
/* check if multiple attributes of the same type are allowed */
|| (((flags & CMS_ATTR_F_ONLY_ONE) != 0)
&& cms_attrib_get(nid, attrs, &lastpos) != NULL)
/* Check if attribute should have exactly one value in its set */
|| (((flags & CMS_ATTR_F_ONE_ATTR_VALUE) != 0)
&& count != 1)
/* There should be at least one value */
|| count == 0)
return 0;
} else {
/* fail if a required attribute is missing */
if (have_attrs
&& ((flags & CMS_ATTR_F_REQUIRED_COND) != 0)
&& (flags & type) != 0)
return 0;
}
return 1;
}
/*
* Check that the signerinfo attributes obey the attribute rules which includes
* the following checks
* - If any signed attributes exist then there must be a Content Type
* and Message Digest attribute in the signed attributes.
* - The countersignature attribute is an optional unsigned attribute only.
* - Content Type, Message Digest, and Signing time attributes are signed
* attributes. Only one instance of each is allowed, with each of these
* attributes containing a single attribute value in its set.
*/
int CMS_si_check_attributes(const CMS_SignerInfo *si)
{
int i;
int have_signed_attrs = (CMS_signed_get_attr_count(si) > 0);
int have_unsigned_attrs = (CMS_unsigned_get_attr_count(si) > 0);
for (i = 0; i < (int)OSSL_NELEM(cms_attribute_properties); ++i) {
int nid = cms_attribute_properties[i].nid;
int flags = cms_attribute_properties[i].flags;
if (!cms_check_attribute(nid, flags, CMS_ATTR_F_SIGNED,
si->signedAttrs, have_signed_attrs)
|| !cms_check_attribute(nid, flags, CMS_ATTR_F_UNSIGNED,
si->unsignedAttrs, have_unsigned_attrs)) {
CMSerr(CMS_F_CMS_SI_CHECK_ATTRIBUTES, CMS_R_ATTRIBUTE_ERROR);
return 0;
}
}
return 1;
}
+4 -1
View File
@@ -1,6 +1,6 @@
/*
* Generated by util/mkerr.pl DO NOT EDIT
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -150,6 +150,8 @@ static const ERR_STRING_DATA CMS_str_functs[] = {
{ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, 0),
"CMS_SignerInfo_verify_content"},
{ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SIGN_RECEIPT, 0), "CMS_sign_receipt"},
{ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SI_CHECK_ATTRIBUTES, 0),
"CMS_si_check_attributes"},
{ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_STREAM, 0), "CMS_stream"},
{ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_UNCOMPRESS, 0), "CMS_uncompress"},
{ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_VERIFY, 0), "CMS_verify"},
@@ -159,6 +161,7 @@ static const ERR_STRING_DATA CMS_str_functs[] = {
static const ERR_STRING_DATA CMS_str_reasons[] = {
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ADD_SIGNER_ERROR), "add signer error"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ATTRIBUTE_ERROR), "attribute error"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CERTIFICATE_ALREADY_PRESENT),
"certificate already present"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CERTIFICATE_HAS_NO_KEYID),
+2
View File
@@ -416,6 +416,8 @@ int cms_RecipientInfo_kari_encrypt(const CMS_ContentInfo *cms,
/* PWRI routines */
int cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
int en_de);
/* SignerInfo routines */
int CMS_si_check_attributes(const CMS_SignerInfo *si);
DECLARE_ASN1_ITEM(CMS_CertificateChoices)
DECLARE_ASN1_ITEM(CMS_DigestedData)
+39 -14
View File
@@ -109,6 +109,27 @@ static void cms_sd_set_version(CMS_SignedData *sd)
}
/*
* RFC 5652 Section 11.1 Content Type
* The content-type attribute within signed-data MUST
* 1) be present if there are signed attributes
* 2) match the content type in the signed-data,
* 3) be a signed attribute.
* 4) not have more than one copy of the attribute.
*
* Note that since the CMS_SignerInfo_sign() always adds the "signing time"
* attribute, the content type attribute MUST be added also.
* Assumptions: This assumes that the attribute does not already exist.
*/
static int cms_set_si_contentType_attr(CMS_ContentInfo *cms, CMS_SignerInfo *si)
{
ASN1_OBJECT *ctype = cms->d.signedData->encapContentInfo->eContentType;
/* Add the contentType attribute */
return CMS_signed_add1_attr_by_NID(si, NID_pkcs9_contentType,
V_ASN1_OBJECT, ctype, -1) > 0;
}
/* Copy an existing messageDigest value */
static int cms_copy_messageDigest(CMS_ContentInfo *cms, CMS_SignerInfo *si)
@@ -325,13 +346,6 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
if (!i)
goto merr;
}
if (flags & CMS_REUSE_DIGEST) {
if (!cms_copy_messageDigest(cms, si))
goto err;
if (!(flags & (CMS_PARTIAL | CMS_KEY_PARAM)) &&
!CMS_SignerInfo_sign(si))
goto err;
}
if (flags & CMS_CADES) {
ESS_SIGNING_CERT *sc = NULL;
ESS_SIGNING_CERT_V2 *sc2 = NULL;
@@ -353,6 +367,15 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
if (!add_sc)
goto err;
}
if (flags & CMS_REUSE_DIGEST) {
if (!cms_copy_messageDigest(cms, si))
goto err;
if (!cms_set_si_contentType_attr(cms, si))
goto err;
if (!(flags & (CMS_PARTIAL | CMS_KEY_PARAM)) &&
!CMS_SignerInfo_sign(si))
goto err;
}
}
if (!(flags & CMS_NOCERTS)) {
@@ -370,8 +393,7 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
goto err;
if (EVP_PKEY_CTX_set_signature_md(si->pctx, md) <= 0)
goto err;
} else if (EVP_DigestSignInit(si->mctx, &si->pctx, md, NULL, pk) <=
0)
} else if (EVP_DigestSignInit(si->mctx, &si->pctx, md, NULL, pk) <= 0)
goto err;
}
@@ -579,8 +601,6 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
*/
if (CMS_signed_get_attr_count(si) >= 0) {
ASN1_OBJECT *ctype =
cms->d.signedData->encapContentInfo->eContentType;
unsigned char md[EVP_MAX_MD_SIZE];
unsigned int mdlen;
if (!EVP_DigestFinal_ex(mctx, md, &mdlen))
@@ -589,9 +609,9 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
V_ASN1_OCTET_STRING, md, mdlen))
goto err;
/* Copy content type across */
if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_contentType,
V_ASN1_OBJECT, ctype, -1) <= 0)
if (!cms_set_si_contentType_attr(cms, si))
goto err;
if (!CMS_SignerInfo_sign(si))
goto err;
} else if (si->pctx) {
@@ -671,6 +691,9 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *si)
goto err;
}
if (!CMS_si_check_attributes(si))
goto err;
if (si->pctx)
pctx = si->pctx;
else {
@@ -717,7 +740,6 @@ int CMS_SignerInfo_sign(CMS_SignerInfo *si)
OPENSSL_free(abuf);
EVP_MD_CTX_reset(mctx);
return 0;
}
int CMS_SignerInfo_verify(CMS_SignerInfo *si)
@@ -732,6 +754,9 @@ int CMS_SignerInfo_verify(CMS_SignerInfo *si)
return -1;
}
if (!CMS_si_check_attributes(si))
return -1;
md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
if (md == NULL)
return -1;