summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2015-06-02 11:00:26 +0200
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2015-06-02 11:00:26 +0200
commit5d0e6706358132e7cd7c8c9904c7399a2f5b5044 (patch)
treedc6a7a8f179654f7569985870e52ed4ed1138fb7
parentb09a79fa336eac47c95788d7fd1d6c2ee0eee2f5 (diff)
downloadgnutls-5d0e6706358132e7cd7c8c9904c7399a2f5b5044.tar.gz
pkcs7 verification: parse the signing time
-rw-r--r--lib/includes/gnutls/pkcs7.h2
-rw-r--r--lib/x509/common.c19
-rw-r--r--lib/x509/pkcs7.c52
3 files changed, 67 insertions, 6 deletions
diff --git a/lib/includes/gnutls/pkcs7.h b/lib/includes/gnutls/pkcs7.h
index d952b2d94e..7955dd601a 100644
--- a/lib/includes/gnutls/pkcs7.h
+++ b/lib/includes/gnutls/pkcs7.h
@@ -78,6 +78,8 @@ typedef struct gnutls_pkcs7_signature_info_st {
gnutls_datum_t issuer_dn;
gnutls_datum_t signer_serial;
gnutls_datum_t issuer_keyid;
+ time_t signing_time;
+ char pad[64];
} gnutls_pkcs7_signature_info_st;
void gnutls_pkcs7_signature_info_deinit(gnutls_pkcs7_signature_info_st *info);
diff --git a/lib/x509/common.c b/lib/x509/common.c
index 321fa7d7f4..1a368ea73b 100644
--- a/lib/x509/common.c
+++ b/lib/x509/common.c
@@ -767,7 +767,7 @@ gtime2generalTime(time_t gtime, char *str_time, size_t str_time_size)
* be something like "tbsCertList.thisUpdate".
*/
#define MAX_TIME 64
-time_t _gnutls_x509_get_time(ASN1_TYPE c2, const char *when, int nochoice)
+time_t _gnutls_x509_get_time(ASN1_TYPE c2, const char *where, int nochoice)
{
char ttime[MAX_TIME];
char name[128];
@@ -775,7 +775,7 @@ time_t _gnutls_x509_get_time(ASN1_TYPE c2, const char *when, int nochoice)
int len, result;
len = sizeof(ttime) - 1;
- result = asn1_read_value(c2, when, ttime, &len);
+ result = asn1_read_value(c2, where, ttime, &len);
if (result != ASN1_SUCCESS) {
gnutls_assert();
return (time_t) (-1);
@@ -784,19 +784,26 @@ time_t _gnutls_x509_get_time(ASN1_TYPE c2, const char *when, int nochoice)
if (nochoice != 0) {
c_time = _gnutls_x509_generalTime2gtime(ttime);
} else {
- _gnutls_str_cpy(name, sizeof(name), when);
+ _gnutls_str_cpy(name, sizeof(name), where);
/* choice */
if (strcmp(ttime, "generalTime") == 0) {
- _gnutls_str_cat(name, sizeof(name),
- ".generalTime");
+ if (name[0] == 0)
+ _gnutls_str_cpy(name, sizeof(name),
+ "generalTime");
+ else
+ _gnutls_str_cat(name, sizeof(name),
+ ".generalTime");
len = sizeof(ttime) - 1;
result = asn1_read_value(c2, name, ttime, &len);
if (result == ASN1_SUCCESS)
c_time =
_gnutls_x509_generalTime2gtime(ttime);
} else { /* UTCTIME */
- _gnutls_str_cat(name, sizeof(name), ".utcTime");
+ if (name[0] == 0)
+ _gnutls_str_cpy(name, sizeof(name), "utcTime");
+ else
+ _gnutls_str_cat(name, sizeof(name), ".utcTime");
len = sizeof(ttime) - 1;
result = asn1_read_value(c2, name, ttime, &len);
if (result == ASN1_SUCCESS)
diff --git a/lib/x509/pkcs7.c b/lib/x509/pkcs7.c
index 3ebfb741da..781d21b350 100644
--- a/lib/x509/pkcs7.c
+++ b/lib/x509/pkcs7.c
@@ -441,6 +441,42 @@ void gnutls_pkcs7_signature_info_deinit(gnutls_pkcs7_signature_info_st *info)
memset(info, 0, sizeof(*info));
}
+static time_t parse_time(gnutls_pkcs7_t pkcs7, const char *root)
+{
+ char tval[128];
+ ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
+ time_t ret;
+ int result, len;
+
+ result = asn1_create_element(_gnutls_get_pkix(), "PKIX1.Time", &c2);
+ if (result != ASN1_SUCCESS) {
+ ret = -1;
+ gnutls_assert();
+ goto cleanup;
+ }
+
+ len = sizeof(tval);
+ result = asn1_read_value(pkcs7->signed_data, root, tval, &len);
+ if (result != ASN1_SUCCESS) {
+ ret = -1;
+ gnutls_assert();
+ goto cleanup;
+ }
+
+ result = _asn1_strict_der_decode(&c2, tval, len, NULL);
+ if (result != ASN1_SUCCESS) {
+ ret = -1;
+ gnutls_assert();
+ goto cleanup;
+ }
+
+ ret = _gnutls_x509_get_time(c2, "", 0);
+
+ cleanup:
+ asn1_delete_structure(&c2);
+ return ret;
+}
+
/**
* gnutls_pkcs7_get_signature_info:
* @pkcs7: should contain a #gnutls_pkcs7_t type
@@ -463,11 +499,13 @@ int gnutls_pkcs7_get_signature_info(gnutls_pkcs7_t pkcs7, unsigned idx, gnutls_p
char oid[MAX_OID_SIZE];
gnutls_pk_algorithm_t pk;
gnutls_sign_algorithm_t sig;
+ unsigned i;
if (pkcs7 == NULL)
return GNUTLS_E_INVALID_REQUEST;
memset(info, 0, sizeof(*info));
+ info->signing_time = -1;
ret = asn1_number_of_elements(pkcs7->signed_data, "signerInfos", &count);
if (ret != ASN1_SUCCESS || idx+1 > (unsigned)count) {
@@ -551,6 +589,20 @@ int gnutls_pkcs7_get_signature_info(gnutls_pkcs7_t pkcs7, unsigned idx, gnutls_p
goto fail;
}
+ /* read the signing time */
+ for (i=0;;i++) {
+ snprintf(root, sizeof(root), "signerInfos.?%u.signedAttrs.?%u.type", idx+1, i+1);
+ len = sizeof(oid)-1;
+ ret = asn1_read_value(pkcs7->signed_data, root, oid, &len);
+ if (ret != ASN1_SUCCESS) {
+ break;
+ }
+
+ if (strcmp(oid, ATTR_SIGNING_TIME) == 0) {
+ snprintf(root, sizeof(root), "signerInfos.?%u.signedAttrs.?%u.values.?1", idx+1, i+1);
+ info->signing_time = parse_time(pkcs7, root);
+ }
+ }
return 0;
fail:
gnutls_pkcs7_signature_info_deinit(info);