aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Brunner <tobias@strongswan.org>2012-05-12 18:15:50 +0200
committerTobias Brunner <tobias@strongswan.org>2012-06-11 17:09:20 +0200
commit6e6d78a561710938188bafd72ad06eb76b6983ec (patch)
tree269c814a805d57d42f6f93fe8a4b178261405dee
parent2bf125f0edca72a7dc5cf94dba0ca4c3e4ca9fa5 (diff)
downloadstrongswan-6e6d78a561710938188bafd72ad06eb76b6983ec.tar.bz2
strongswan-6e6d78a561710938188bafd72ad06eb76b6983ec.tar.xz
Changed memory management and call logic in PKCS#7 parser/generator.
-rw-r--r--src/libstrongswan/crypto/pkcs7.c168
-rw-r--r--src/libstrongswan/crypto/pkcs7.h3
2 files changed, 86 insertions, 85 deletions
diff --git a/src/libstrongswan/crypto/pkcs7.c b/src/libstrongswan/crypto/pkcs7.c
index 749e8818f..c5fa8c02d 100644
--- a/src/libstrongswan/crypto/pkcs7.c
+++ b/src/libstrongswan/crypto/pkcs7.c
@@ -56,11 +56,6 @@ struct private_pkcs7_t {
chunk_t content;
/**
- * Has the content already been parsed?
- */
- bool parsed;
-
- /**
* ASN.1 parsing start level
*/
u_int level;
@@ -100,6 +95,69 @@ METHOD(pkcs7_t, is_envelopedData, bool,
}
/**
+ * ASN.1 definition of the PKCS#7 ContentInfo type
+ */
+static const asn1Object_t contentInfoObjects[] = {
+ { 0, "contentInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
+ { 1, "contentType", ASN1_OID, ASN1_BODY }, /* 1 */
+ { 1, "content", ASN1_CONTEXT_C_0, ASN1_OPT |
+ ASN1_BODY }, /* 2 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 3 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define PKCS7_INFO_TYPE 1
+#define PKCS7_INFO_CONTENT 2
+
+/**
+ * Parse PKCS#7 contentInfo object
+ */
+static bool parse_contentInfo(private_pkcs7_t *this)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+ bool success = FALSE;
+
+ if (!this->data.ptr)
+ {
+ return FALSE;
+ }
+
+ parser = asn1_parser_create(contentInfoObjects, this->data);
+ parser->set_top_level(parser, this->level);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ if (objectID == PKCS7_INFO_TYPE)
+ {
+ this->type = asn1_known_oid(object);
+ if (this->type < OID_PKCS7_DATA ||
+ this->type > OID_PKCS7_ENCRYPTED_DATA)
+ {
+ DBG1(DBG_LIB, "unknown pkcs7 content type");
+ goto end;
+ }
+ }
+ else if (objectID == PKCS7_INFO_CONTENT && object.len > 0)
+ {
+ chunk_free(&this->content);
+ this->content = chunk_clone(object);
+ }
+ }
+ success = parser->success(parser);
+
+ if (success)
+ {
+ this->level += 2;
+ chunk_free(&this->data);
+ }
+
+end:
+ parser->destroy(parser);
+ return success;
+}
+
+/**
* Check whether to abort the requested parsing
*/
static bool abort_parsing(private_pkcs7_t *this, int type)
@@ -110,30 +168,27 @@ static bool abort_parsing(private_pkcs7_t *this, int type)
oid_names[type].name);
return TRUE;
}
- if (this->parsed)
- {
- DBG1(DBG_LIB, "pkcs7 content has already been parsed");
- return TRUE;
- }
- this->parsed = TRUE;
return FALSE;
}
METHOD(pkcs7_t, parse_data, bool,
private_pkcs7_t *this)
{
- chunk_t data = this->content;
+ chunk_t data;
- if (abort_parsing(this, OID_PKCS7_DATA))
+ if (!parse_contentInfo(this) ||
+ abort_parsing(this, OID_PKCS7_DATA))
{
return FALSE;
}
+ data = this->content;
if (data.len == 0)
{
this->data = chunk_empty;
return TRUE;
}
- if (asn1_parse_simple_object(&data, ASN1_OCTET_STRING, this->level, "data"))
+ if (asn1_parse_simple_object(&data, ASN1_OCTET_STRING,
+ this->level, "data"))
{
this->data = chunk_clone(data);
return TRUE;
@@ -202,7 +257,8 @@ METHOD(pkcs7_t, parse_signedData, bool,
chunk_t encrypted_digest = chunk_empty;
- if (abort_parsing(this, OID_PKCS7_SIGNED_DATA))
+ if (!parse_contentInfo(this) ||
+ abort_parsing(this, OID_PKCS7_SIGNED_DATA))
{
return FALSE;
}
@@ -225,20 +281,14 @@ METHOD(pkcs7_t, parse_signedData, bool,
break;
case PKCS7_SIGNED_CONTENT_INFO:
{
- chunk_t pureData;
pkcs7_t *data = pkcs7_create_from_chunk(object, level+1);
- if (data == NULL)
- {
- goto end;
- }
- if (!data->parse_data(data))
+ if (!data || !data->parse_data(data))
{
- data->destroy(data);
+ DESTROY_IF(data);
goto end;
}
- pureData = data->get_data(data);
- this->data = (pureData.len) ? chunk_clone(pureData) : chunk_empty;
+ this->data = chunk_clone(data->get_data(data));
data->destroy(data);
break;
}
@@ -443,7 +493,8 @@ METHOD(pkcs7_t, parse_envelopedData, bool,
crypter_t *crypter = NULL;
- if (abort_parsing(this, OID_PKCS7_ENVELOPED_DATA))
+ if (!parse_contentInfo(this) ||
+ abort_parsing(this, OID_PKCS7_ENVELOPED_DATA))
{
return FALSE;
}
@@ -813,7 +864,9 @@ METHOD(pkcs7_t, build_envelopedData, bool,
ASN1_INTEGER_0,
asn1_wrap(ASN1_SET, "m", recipientInfo),
encryptedContentInfo);
+ chunk_free(&this->data);
this->type = OID_PKCS7_ENVELOPED_DATA;
+ this->data = get_contentInfo(this);
}
return TRUE;
}
@@ -900,7 +953,6 @@ METHOD(pkcs7_t, build_signedData, bool,
this->data = get_contentInfo(this);
chunk_free(&this->content);
- this->type = OID_PKCS7_SIGNED_DATA;
cert->get_encoding(cert, CERT_ASN1_DER, &encoding);
this->content = asn1_wrap(ASN1_SEQUENCE, "cmcmm",
@@ -909,6 +961,9 @@ METHOD(pkcs7_t, build_signedData, bool,
this->data,
asn1_wrap(ASN1_CONTEXT_C_0, "m", encoding),
asn1_wrap(ASN1_SET, "m", signerInfo));
+ chunk_free(&this->data);
+ this->type = OID_PKCS7_SIGNED_DATA;
+ this->data = get_contentInfo(this);
return TRUE;
}
@@ -924,57 +979,6 @@ METHOD(pkcs7_t, destroy, void,
}
/**
- * ASN.1 definition of the PKCS#7 ContentInfo type
- */
-static const asn1Object_t contentInfoObjects[] = {
- { 0, "contentInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "contentType", ASN1_OID, ASN1_BODY }, /* 1 */
- { 1, "content", ASN1_CONTEXT_C_0, ASN1_OPT |
- ASN1_BODY }, /* 2 */
- { 1, "end opt", ASN1_EOC, ASN1_END }, /* 3 */
- { 0, "exit", ASN1_EOC, ASN1_EXIT }
-};
-#define PKCS7_INFO_TYPE 1
-#define PKCS7_INFO_CONTENT 2
-
-/**
- * Parse PKCS#7 contentInfo object
- */
-static bool parse_contentInfo(chunk_t blob, u_int level0, private_pkcs7_t *cInfo)
-{
- asn1_parser_t *parser;
- chunk_t object;
- int objectID;
- bool success = FALSE;
-
- parser = asn1_parser_create(contentInfoObjects, blob);
- parser->set_top_level(parser, level0);
-
- while (parser->iterate(parser, &objectID, &object))
- {
- if (objectID == PKCS7_INFO_TYPE)
- {
- cInfo->type = asn1_known_oid(object);
- if (cInfo->type < OID_PKCS7_DATA
- || cInfo->type > OID_PKCS7_ENCRYPTED_DATA)
- {
- DBG1(DBG_LIB, "unknown pkcs7 content type");
- goto end;
- }
- }
- else if (objectID == PKCS7_INFO_CONTENT && object.len > 0)
- {
- cInfo->content = chunk_clone(object);
- }
- }
- success = parser->success(parser);
-
-end:
- parser->destroy(parser);
- return success;
-}
-
-/**
* Generic private constructor
*/
static private_pkcs7_t *pkcs7_create_empty(void)
@@ -1013,12 +1017,9 @@ pkcs7_t *pkcs7_create_from_chunk(chunk_t chunk, u_int level)
{
private_pkcs7_t *this = pkcs7_create_empty();
- this->level = level + 2;
- if (!parse_contentInfo(chunk, level, this))
- {
- destroy(this);
- return NULL;
- }
+ this->level = level;
+ this->data = chunk_clone(chunk);
+
return &this->public;
}
@@ -1030,7 +1031,6 @@ pkcs7_t *pkcs7_create_from_data(chunk_t data)
private_pkcs7_t *this = pkcs7_create_empty();
this->data = chunk_clone(data);
- this->parsed = TRUE;
return &this->public;
}
diff --git a/src/libstrongswan/crypto/pkcs7.h b/src/libstrongswan/crypto/pkcs7.h
index 531acb373..98b3ca863 100644
--- a/src/libstrongswan/crypto/pkcs7.h
+++ b/src/libstrongswan/crypto/pkcs7.h
@@ -64,7 +64,8 @@ struct pkcs7_t {
bool (*parse_data) (pkcs7_t *this);
/**
- * Parse a PKCS#7 signedData content.
+ * Parse a PKCS#7 signedData content. The contained PKCS#7 data is parsed
+ * and verified.
*
* @param cacert cacert used to verify the signature
* @return TRUE if parsing was successful