diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2003-06-23 06:52:34 +0000 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2003-06-23 06:52:34 +0000 |
commit | 65ee78490288377151bb6c9ea3e5fb53a46adce0 (patch) | |
tree | 25de3e3b04e6ddb2b97f5e66ccf43c010b62d7a9 | |
parent | b9d6179114200c574d572858dbe36a2b49bbc268 (diff) | |
download | gnutls-65ee78490288377151bb6c9ea3e5fb53a46adce0.tar.gz |
some pkcs12 improvements.
-rw-r--r-- | lib/gnutls_errors.c | 1 | ||||
-rw-r--r-- | lib/x509/common.h | 2 | ||||
-rw-r--r-- | lib/x509/pkcs12.c | 60 | ||||
-rw-r--r-- | lib/x509/pkcs12.h | 9 | ||||
-rw-r--r-- | lib/x509/pkcs12_bag.c | 23 | ||||
-rw-r--r-- | lib/x509/privkey_pkcs8.c | 30 |
6 files changed, 86 insertions, 39 deletions
diff --git a/lib/gnutls_errors.c b/lib/gnutls_errors.c index 43d8a4c988..e8c9101204 100644 --- a/lib/gnutls_errors.c +++ b/lib/gnutls_errors.c @@ -43,6 +43,7 @@ static gnutls_error_entry error_algorithms[] = { /* "Short Description", Error code define, critical (0,1) -- 1 in most cases */ ERROR_ENTRY("Success.", GNUTLS_E_SUCCESS, 0 ), ERROR_ENTRY("Could not negotiate a supported cipher suite.", GNUTLS_E_UNKNOWN_CIPHER_SUITE, 1 ), + ERROR_ENTRY("The cipher type is unknown.", GNUTLS_E_UNKNOWN_CIPHER_TYPE, 1 ), ERROR_ENTRY("The certificate and the given key do not match.", GNUTLS_E_CERTIFICATE_KEY_MISMATCH, 1 ), ERROR_ENTRY("Could not negotiate a supported compression method.", GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM, 1 ), ERROR_ENTRY("An unknown public key algorithm was encountered.", GNUTLS_E_UNKNOWN_PK_ALGORITHM, 1 ), diff --git a/lib/x509/common.h b/lib/x509/common.h index f40480d377..4564cd61c0 100644 --- a/lib/x509/common.h +++ b/lib/x509/common.h @@ -49,5 +49,3 @@ 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_decrypt_pkcs7_encrypted_data( const gnutls_datum* data, - const char* password, gnutls_datum* dec); diff --git a/lib/x509/pkcs12.c b/lib/x509/pkcs12.c index e60df40dad..dfe2220639 100644 --- a/lib/x509/pkcs12.c +++ b/lib/x509/pkcs12.c @@ -234,11 +234,6 @@ int gnutls_pkcs12_export( gnutls_pkcs12 pkcs12, output_data, output_data_size); } -#define BAG_PKCS8_KEY "1.2.840.113549.1.12.10.1.1" -#define BAG_PKCS8_ENCRYPTED_KEY "1.2.840.113549.1.12.10.1.2" -#define BAG_CERTIFICATE "1.2.840.113549.1.12.10.1.3" -#define BAG_CRL "1.2.840.113549.1.12.10.1.4" - static int _oid2bag( const char* oid) { if (strcmp(oid, BAG_PKCS8_KEY)==0) @@ -254,26 +249,18 @@ static int _oid2bag( const char* oid) } - -static -int _parse_safe_contents( ASN1_TYPE sc, const char* sc_name, gnutls_pkcs12_bag bag) +/* Decodes the SafeContents, and puts the output in + * the given bag. + */ +int +_pkcs12_decode_safe_contents( const gnutls_datum* content, gnutls_pkcs12_bag bag) { char oid[128]; ASN1_TYPE c2 = ASN1_TYPE_EMPTY; -gnutls_datum content = { NULL, 0 }; int len, result; int bag_type; - /* Step 1. Extract the content. - */ - - result = _gnutls_x509_read_value(sc, sc_name, &content, 1); - if (result < 0) { - gnutls_assert(); - goto cleanup; - } - - /* Step 2. Extract the SEQUENCE. + /* Step 1. Extract the SEQUENCE. */ if ((result=asn1_create_element @@ -283,13 +270,12 @@ int bag_type; goto cleanup; } - result = asn1_der_decoding(&c2, content.data, content.size, NULL); + result = asn1_der_decoding(&c2, content->data, content->size, NULL); if (result != ASN1_SUCCESS) { gnutls_assert(); result = _gnutls_asn2err(result); goto cleanup; } - _gnutls_free_datum(&content); len = sizeof(oid); result = asn1_read_value(c2, "?1.bagId", oid, &len); @@ -310,7 +296,6 @@ int bag_type; /* Read the Bag Value */ - result = _gnutls_x509_read_value( c2, "?1.bagValue", &bag->data, 0); if (result < 0) { gnutls_assert(); @@ -325,6 +310,37 @@ int bag_type; cleanup: if (c2) asn1_delete_structure(&c2); + return result; + +} + + +static +int _parse_safe_contents( ASN1_TYPE sc, const char* sc_name, gnutls_pkcs12_bag bag) +{ +gnutls_datum content = { NULL, 0 }; +int result; + + /* Step 1. Extract the content. + */ + + result = _gnutls_x509_read_value(sc, sc_name, &content, 1); + if (result < 0) { + gnutls_assert(); + goto cleanup; + } + + result = _pkcs12_decode_safe_contents( &content, bag); + if (result < 0) { + gnutls_assert(); + goto cleanup; + } + + _gnutls_free_datum( &content); + + return 0; + + cleanup: _gnutls_free_datum( &content); return result; } diff --git a/lib/x509/pkcs12.h b/lib/x509/pkcs12.h index 272fbb4608..c337fd1275 100644 --- a/lib/x509/pkcs12.h +++ b/lib/x509/pkcs12.h @@ -18,6 +18,11 @@ typedef struct gnutls_pkcs12_bag_int { gnutls_pkcs12_bag_type type; } gnutls_pkcs12_bag_int; +#define BAG_PKCS8_KEY "1.2.840.113549.1.12.10.1.1" +#define BAG_PKCS8_ENCRYPTED_KEY "1.2.840.113549.1.12.10.1.2" +#define BAG_CERTIFICATE "1.2.840.113549.1.12.10.1.3" +#define BAG_CRL "1.2.840.113549.1.12.10.1.4" + typedef struct gnutls_pkcs12_int *gnutls_pkcs12; typedef struct gnutls_pkcs12_bag_int *gnutls_pkcs12_bag; @@ -35,3 +40,7 @@ void gnutls_pkcs12_bag_deinit(gnutls_pkcs12_bag bag); int _pkcs12_string_to_key (int id, const char *salt, int salt_size, int iter, const char *pw, int req_keylen, unsigned char *keybuf); + +int _gnutls_x509_decrypt_pkcs7_encrypted_data( const gnutls_datum* data, + const char* password, gnutls_datum* dec); +int _pkcs12_decode_safe_contents( const gnutls_datum* content, gnutls_pkcs12_bag bag); diff --git a/lib/x509/pkcs12_bag.c b/lib/x509/pkcs12_bag.c index 2c3f397ac0..f2145c43d1 100644 --- a/lib/x509/pkcs12_bag.c +++ b/lib/x509/pkcs12_bag.c @@ -107,20 +107,31 @@ int gnutls_pkcs12_bag_decrypt(gnutls_pkcs12_bag bag, const char* pass) { int ret; gnutls_datum dec; +ASN1_TYPE sc = ASN1_TYPE_EMPTY; ret = _gnutls_x509_decrypt_pkcs7_encrypted_data( &bag->data, pass, &dec); if (ret < 0) { - gnutls_assert(); + gnutls_assert(); return ret; } - - /* decryption succeeded */ - + + /* decryption succeeded. Now decode the SafeContents + * stuff, and parse it. + */ + _gnutls_free_datum( &bag->data); - - bag->data = dec; + + ret = _pkcs12_decode_safe_contents( &dec, bag); + + _gnutls_free_datum( &dec); + + if (ret < 0) { + gnutls_assert(); + return ret; + } + return 0; } diff --git a/lib/x509/privkey_pkcs8.c b/lib/x509/privkey_pkcs8.c index 218bdba32c..88763b6da5 100644 --- a/lib/x509/privkey_pkcs8.c +++ b/lib/x509/privkey_pkcs8.c @@ -43,7 +43,8 @@ typedef enum schema_id { PBES2, /* the stuff in PKCS #5 */ - PKCS12_3DES_SHA1 /* the fucking stuff in PKCS #12 */ + PKCS12_3DES_SHA1, /* the fucking stuff in PKCS #12 */ + PKCS12_ARCFOUR_SHA1 } schema_id; #define PBES2_OID "1.2.840.113549.1.5.13" @@ -51,7 +52,8 @@ typedef enum schema_id { #define DES_EDE3_CBC_OID "1.2.840.113549.3.7" /* oid_pbeWithSHAAnd3_KeyTripleDES_CBC */ -#define PBE_3DES_SHA1_OID "1.2.840.113549.1.12.1.3" +#define PKCS12_PBE_3DES_SHA1_OID "1.2.840.113549.1.12.1.3" +#define PKCS12_PBE_ARCFOUR_SHA1_OID "1.2.840.113549.1.12.1.1" struct pbkdf2_params { opaque salt[32]; @@ -105,9 +107,12 @@ inline static int check_schema(const char *oid) if (strcmp(oid, PBES2_OID) == 0) return PBES2; - if (strcmp(oid, PBE_3DES_SHA1_OID) == 0) + if (strcmp(oid, PKCS12_PBE_3DES_SHA1_OID) == 0) return PKCS12_3DES_SHA1; + if (strcmp(oid, PKCS12_PBE_ARCFOUR_SHA1_OID) == 0) + return PKCS12_ARCFOUR_SHA1; + _gnutls_x509_log("PKCS encryption schema OID '%s' is unsupported.\n", oid); return GNUTLS_E_UNKNOWN_CIPHER_TYPE; @@ -472,6 +477,16 @@ int read_pkcs_schema_params(schema_id schema, const char* password, break; case PKCS12_3DES_SHA1: + case PKCS12_ARCFOUR_SHA1: + + if ((schema) == PKCS12_3DES_SHA1) { + enc_params->cipher = GNUTLS_CIPHER_3DES_CBC; + enc_params->iv_size = 8; + } else { + enc_params->cipher = GNUTLS_CIPHER_ARCFOUR_128; + enc_params->iv_size = 0; + } + if ((result = asn1_create_element(_gnutls_get_pkix(), "PKIX1.pkcs-12-PbeParams", @@ -499,10 +514,9 @@ int read_pkcs_schema_params(schema_id schema, const char* password, goto error; } - enc_params->cipher = GNUTLS_CIPHER_3DES_CBC; - enc_params->iv_size = 8; - _pkcs12_string_to_key( 2/*IV*/, kdf_params->salt, kdf_params->salt_size, - kdf_params->iter_count, password, 8, enc_params->iv); + if (enc_params->iv_size) + _pkcs12_string_to_key( 2/*IV*/, kdf_params->salt, kdf_params->salt_size, + kdf_params->iter_count, password, enc_params->iv_size, enc_params->iv); asn1_delete_structure(&pbes2_asn); @@ -1520,8 +1534,6 @@ int _gnutls_x509_decrypt_pkcs7_encrypted_data(const gnutls_datum * data, goto error; } - /* we only support PBES2 - */ if ((result = check_schema(enc_oid)) < 0) { gnutls_assert(); goto error; |