diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2003-06-27 13:40:27 +0000 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2003-06-27 13:40:27 +0000 |
commit | 4168761ce305537694cffabcde6dcfb3bb3b8464 (patch) | |
tree | e08181df989e848c95aabb0ff0950ce0f89ac43f | |
parent | ce784e5c99ddddb454ab402d7ed423c9eee03d3b (diff) | |
download | gnutls-4168761ce305537694cffabcde6dcfb3bb3b8464.tar.gz |
Added stuff needed to read PKCS #12 bag attributes.
-rw-r--r-- | includes/gnutls/x509.h | 11 | ||||
-rw-r--r-- | lib/x509/common.h | 5 | ||||
-rw-r--r-- | lib/x509/dn.c | 43 | ||||
-rw-r--r-- | lib/x509/dn.h | 2 | ||||
-rw-r--r-- | lib/x509/pkcs12.c | 59 | ||||
-rw-r--r-- | lib/x509/pkcs12.h | 5 |
6 files changed, 119 insertions, 6 deletions
diff --git a/includes/gnutls/x509.h b/includes/gnutls/x509.h index 8b195ae804..4afa12bf7d 100644 --- a/includes/gnutls/x509.h +++ b/includes/gnutls/x509.h @@ -309,6 +309,17 @@ int gnutls_pkcs12_bag_init(gnutls_pkcs12_bag * bag); void gnutls_pkcs12_bag_deinit(gnutls_pkcs12_bag bag); int gnutls_pkcs12_bag_get_count(gnutls_pkcs12_bag bag); +int gnutls_pkcs12_bag_get_key_id(gnutls_pkcs12_bag bag, int indx, + gnutls_datum* id); +int gnutls_pkcs12_bag_set_key_id(gnutls_pkcs12_bag bag, int indx, + const gnutls_datum* id); + +int gnutls_pkcs12_bag_get_friendly_name(gnutls_pkcs12_bag bag, int indx, + char **name); +int gnutls_pkcs12_bag_set_friendly_name(gnutls_pkcs12_bag bag, int indx, + const char* name); + + #ifdef __cplusplus } #endif diff --git a/lib/x509/common.h b/lib/x509/common.h index 0839544e95..fa3e00c5e7 100644 --- a/lib/x509/common.h +++ b/lib/x509/common.h @@ -52,3 +52,8 @@ int _gnutls_x509_export_int( ASN1_TYPE asn1_data, int _gnutls_x509_read_value( ASN1_TYPE c, const char* root, gnutls_datum *ret, int str); int _gnutls_x509_write_value( ASN1_TYPE c, const char* root, const gnutls_datum* data, int str); + +int _gnutls_x509_encode_and_write_attribute( const char* given_oid, ASN1_TYPE asn1_struct, + const char* where, const unsigned char* data, int sizeof_data, int multi); +int _gnutls_x509_decode_and_read_attribute(ASN1_TYPE asn1_struct, const char* where, + char* oid, int oid_size, gnutls_datum* value, int multi); diff --git a/lib/x509/dn.c b/lib/x509/dn.c index fcf565f271..7d227f273d 100644 --- a/lib/x509/dn.c +++ b/lib/x509/dn.c @@ -91,7 +91,7 @@ int _gnutls_x509_parse_dn(ASN1_TYPE asn1_struct, char tmpbuffer2[64]; char tmpbuffer3[64]; char counter[MAX_INT_DIGITS]; - char value[200]; + char value[256]; char escaped[256]; const char *ldap_desc; char oid[128]; @@ -590,6 +590,47 @@ fprintf(stderr, "%s %s\n", given_oid, val_name); return 0; } +/* Decodes an X.509 Attribute (if multi==1) or an AttributeTypeAndValue + * otherwise. + */ +int _gnutls_x509_decode_and_read_attribute(ASN1_TYPE asn1_struct, const char* where, + char* oid, int oid_size, gnutls_datum* value, int multi) +{ +char tmpbuffer[128]; +int len, result; + + /* Read the OID + */ + _gnutls_str_cpy(tmpbuffer, sizeof(tmpbuffer), where); + _gnutls_str_cat(tmpbuffer, sizeof(tmpbuffer), ".type"); + + len = oid_size - 1; + result = asn1_read_value(asn1_struct, tmpbuffer, oid, &len); + + if (result != ASN1_SUCCESS) { + gnutls_assert(); + result = _gnutls_asn2err(result); + return result; + } + + /* Read the Value + */ + + _gnutls_str_cpy(tmpbuffer, sizeof(tmpbuffer), where); + _gnutls_str_cat(tmpbuffer, sizeof(tmpbuffer), ".value"); + + if (multi) + _gnutls_str_cat(tmpbuffer, sizeof(tmpbuffer), "s.?1"); /* .values.?1 */ + + result = _gnutls_x509_read_value( asn1_struct, tmpbuffer, value, 0); + if (result < 0) { + gnutls_assert(); + return result; + } + + return 0; + +} /* Sets an X509 DN in the asn1_struct, and puts the given OID in the DN. * The input is assumed to be raw data. diff --git a/lib/x509/dn.h b/lib/x509/dn.h index 0b260b57c3..dd6d731c27 100644 --- a/lib/x509/dn.h +++ b/lib/x509/dn.h @@ -25,7 +25,5 @@ int _gnutls_x509_set_dn_oid(ASN1_TYPE asn1_struct, const char* asn1_rdn_name, const char* oid, const char *name, int sizeof_name); -int _gnutls_x509_encode_and_write_attribute( const char* given_oid, ASN1_TYPE asn1_struct, - const char* where, const unsigned char* data, int sizeof_data, int multi); #endif diff --git a/lib/x509/pkcs12.c b/lib/x509/pkcs12.c index 309eefec89..c680bc971e 100644 --- a/lib/x509/pkcs12.c +++ b/lib/x509/pkcs12.c @@ -263,6 +263,17 @@ static const char* bag2oid( int bag) return NULL; } +static inline +char* ucs2_to_ascii( char* data, int size) { +int i; + + for (i=0;i<size/2;i++) + data[i] = data[i*2 + 1]; + data[i] = 0; + + return data; +} + /* Decodes the SafeContents, and puts the output in * the given bag. */ @@ -273,7 +284,8 @@ char oid[128], root[128]; ASN1_TYPE c2 = ASN1_TYPE_EMPTY; int len, result; int bag_type; -int count = 0, i; +gnutls_datum attr_val; +int count = 0, i, attributes, j; char counter[MAX_INT_DIGITS]; /* Step 1. Extract the SEQUENCE. @@ -355,6 +367,49 @@ char counter[MAX_INT_DIGITS]; _gnutls_free_datum( &tmp); } + /* read the bag attributes + */ + _gnutls_str_cpy( root, sizeof(root), "?"); + _gnutls_int2str( i+1, counter); + _gnutls_str_cat( root, sizeof(root), counter); + _gnutls_str_cat( root, sizeof(root), ".bagAttributes"); + + result = asn1_number_of_elements( c2, root, &attributes); + if (result != ASN1_SUCCESS) { + gnutls_assert(); + result = _gnutls_asn2err(result); + goto cleanup; + } + + if (attributes < 0) attributes = 1; + + for (j=0;j<attributes;j++) { + + _gnutls_str_cpy( root, sizeof(root), "?"); + _gnutls_int2str( i+1, counter); + _gnutls_str_cat( root, sizeof(root), counter); + _gnutls_str_cat( root, sizeof(root), ".bagAttributes.?"); + _gnutls_int2str( j+1, counter); + _gnutls_str_cat( root, sizeof(root), counter); + + result = _gnutls_x509_decode_and_read_attribute( + c2, root, oid, sizeof(oid), &attr_val, 1); + if (result < 0) { + gnutls_assert(); + goto cleanup; + } + + + if (strcmp( oid, KEY_ID_OID)==0) + bag->element[i].local_key_id = attr_val; + else if (strcmp( oid, FRIENDLY_NAME_OID)==0) + bag->element[i].friendly_name = ucs2_to_ascii( attr_val.data, attr_val.size); + else { + _gnutls_x509_log( "Unknown PKCS12 Bag Attribute OID '%s'\n", oid); + } + } + + bag->element[i].type = bag_type; } @@ -747,8 +802,6 @@ int gnutls_pkcs12_generate_mac(gnutls_pkcs12 pkcs12, const char* pass) return result; } -#define FRIENDLY_NAME_OID "1.2.840.113549.1.9.20" -#define KEY_ID_OID "1.2.840.113549.1.9.21" static int write_attributes( gnutls_pkcs12_bag bag, int elem, ASN1_TYPE c2, const char* where) { int result; diff --git a/lib/x509/pkcs12.h b/lib/x509/pkcs12.h index 2c91c9269c..a36fbf5b65 100644 --- a/lib/x509/pkcs12.h +++ b/lib/x509/pkcs12.h @@ -38,6 +38,11 @@ typedef struct gnutls_pkcs12_bag_int { #define DATA_OID "1.2.840.113549.1.7.1" #define ENC_DATA_OID "1.2.840.113549.1.7.6" +/* Bag attributes + */ +#define FRIENDLY_NAME_OID "1.2.840.113549.1.9.20" +#define KEY_ID_OID "1.2.840.113549.1.9.21" + typedef struct gnutls_pkcs12_int *gnutls_pkcs12; typedef struct gnutls_pkcs12_bag_int *gnutls_pkcs12_bag; |