From a60b0ea330be12bce23dbae71c2db26040573a05 Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Wed, 29 Sep 2010 18:29:56 -0400 Subject: [PATCH 028/150] - add some OID info for the various types of data we sign or envelope --- src/plugins/preauth/pkinit/pkinit_crypto_nss.c | 155 +++++++++++++++++++++++- 1 files changed, 152 insertions(+), 3 deletions(-) diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_nss.c b/src/plugins/preauth/pkinit/pkinit_crypto_nss.c index 129f8ac..e3e0678 100644 --- a/src/plugins/preauth/pkinit/pkinit_crypto_nss.c +++ b/src/plugins/preauth/pkinit/pkinit_crypto_nss.c @@ -46,6 +46,7 @@ #include #include #include +#include #define CONFIGDIR "/home/nalin/projects/krb5/pkinit/src/plugins/preauth/pkinit" /* FIXME */ #define NULLCX NULL /* FIXME */ @@ -1433,6 +1434,37 @@ pkinit_get_kdc_cert(krb5_context context, return 0; } +/* Typed data that we return as e-data. */ +struct typed_datum { + SECItem td_type, td_data; +}; +static const SEC_ASN1Template +typed_datum_template[] = { + { + .kind = SEC_ASN1_SEQUENCE, + .offset = 0, + .sub = NULL, + .size = sizeof(struct typed_datum), + }, + { + .kind = SEC_ASN1_CONTEXT_SPECIFIC | 0 | + SEC_ASN1_EXPLICIT | + SEC_ASN1_CONSTRUCTED, + .offset = offsetof(struct typed_datum, td_type), + .sub = SEC_IntegerTemplate, + .size = sizeof(SECItem), + }, + { + .kind = SEC_ASN1_CONTEXT_SPECIFIC | 1 | + SEC_ASN1_EXPLICIT | + SEC_ASN1_CONSTRUCTED, + .offset = offsetof(struct typed_datum, td_data), + .sub = SEC_OctetStringTemplate, + .size = sizeof(SECItem), + }, + {0, 0, NULL, 0}, +}; + krb5_error_code pkinit_create_td_dh_parameters(krb5_context context, pkinit_plg_crypto_context plg_cryptoctx, @@ -1984,6 +2016,73 @@ crypto_check_cert_eku(krb5_context context, return 0; } +static unsigned char oid_pkinit_auth_data_bytes[] = + {0x2b, 0x06, 0x01, 0x05, 0x02, 0x03, 0x01}; +static const SECOidData +oid_pkinit_auth_data = { + .oid = { + .data = oid_pkinit_auth_data_bytes, + .len = 7, + }, + .offset = 0, + .desc = "PKINIT Authentication Data", + .mechanism = 0, + .supportedExtension = UNSUPPORTED_CERT_EXTENSION, +}; +static const SECOidTag +get_pkinit_data_auth_data_tag(void) +{ + static SECOidTag tag = 0; + if (tag == 0) { + tag = SECOID_AddEntry(&oid_pkinit_auth_data); + } + return tag; +} +static unsigned char oid_pkinit_rkey_data_bytes[] = + {0x2b, 0x06, 0x01, 0x05, 0x02, 0x03, 0x03}; +static const SECOidData +oid_pkinit_rkey_data = { + .oid = { + .data = oid_pkinit_rkey_data_bytes, + .len = 7, + }, + .offset = 0, + .desc = "PKINIT Reply Key Data", + .mechanism = 0, + .supportedExtension = UNSUPPORTED_CERT_EXTENSION, +}; +static const SECOidTag +get_pkinit_data_rkey_data_tag(void) +{ + static SECOidTag tag = 0; + if (tag == 0) { + tag = SECOID_AddEntry(&oid_pkinit_rkey_data); + } + return tag; +} +static unsigned char oid_pkinit_dhkey_data_bytes[] = + {0x2b, 0x06, 0x01, 0x05, 0x02, 0x03, 0x02}; +static const SECOidData +oid_pkinit_dhkey_data = { + .oid = { + .data = oid_pkinit_dhkey_data_bytes, + .len = 7, + }, + .offset = 0, + .desc = "PKINIT DH Reply Key Data", + .mechanism = 0, + .supportedExtension = UNSUPPORTED_CERT_EXTENSION, +}; +static const SECOidTag +get_pkinit_data_dhkey_data_tag(void) +{ + static SECOidTag tag = 0; + if (tag == 0) { + tag = SECOID_AddEntry(&oid_pkinit_dhkey_data); + } + return tag; +} + #ifdef DEBUG_DER static void derdump(unsigned char *data, unsigned int length) @@ -2251,6 +2350,34 @@ cms_signeddata_create(krb5_context context, NSSCMSSignerInfo *signer; PLArenaPool *pool; SECItem plain, encoded; + SECOidTag digest, encapsulated_type_tag; + PRBool add_signed_attributes; + + switch (cms_msg_type) { + case CMS_SIGN_DRAFT9: + digest = SEC_OID_MD5; + add_signed_attributes = PR_FALSE; + encapsulated_type_tag = get_pkinit_data_auth_data_tag(); + break; + case CMS_SIGN_CLIENT: + digest = SEC_OID_SHA1; + add_signed_attributes = PR_TRUE; + encapsulated_type_tag = get_pkinit_data_auth_data_tag(); + break; + case CMS_SIGN_SERVER: + digest = SEC_OID_SHA1; + add_signed_attributes = PR_TRUE; + encapsulated_type_tag = get_pkinit_data_dhkey_data_tag(); + break; + case CMS_ENVEL_SERVER: + digest = SEC_OID_SHA1; + add_signed_attributes = PR_FALSE; + encapsulated_type_tag = get_pkinit_data_rkey_data_tag(); + break; + default: + return ENOSYS; + break; + } if (id_cryptoctx->id_cert == NULL) { return ENOENT; @@ -2288,7 +2415,7 @@ cms_signeddata_create(krb5_context context, /* Create a signer and add it to the signed-data pointer. */ signer = NSS_CMSSignerInfo_Create(msg, id_cryptoctx->id_cert, - SEC_OID_SHA1); + digest); if (signer == NULL) { PORT_FreeArena(pool, PR_TRUE); return ENOMEM; @@ -2296,31 +2423,53 @@ cms_signeddata_create(krb5_context context, if (NSS_CMSSignerInfo_IncludeCerts(signer, NSSCMSCM_CertChainWithRoot, certUsageAnyCA) != SECSuccess) { PORT_FreeArena(pool, PR_TRUE); + pkiDebug("%s: error setting IncludeCerts\n", __FUNCTION__); return ENOMEM; } if (NSS_CMSSignedData_AddSignerInfo(sdata, signer) != SECSuccess) { PORT_FreeArena(pool, PR_TRUE); return ENOMEM; } + if (add_signed_attributes) { + /* The presence of any signed attribute means the digest + * becomes a signed attribute, too. */ + if (NSS_CMSSignerInfo_AddSigningTime(signer, + PR_Now()) != SECSuccess) { + PORT_FreeArena(pool, PR_TRUE); + pkiDebug("%s: error adding signing time\n", + __FUNCTION__); + return ENOMEM; + } + } /* Set the raw data as the contents for the signed-data pointer. */ - plain.data = payload; - plain.len = payload_len; info = NSS_CMSSignedData_GetContentInfo(sdata); if (info == NULL) { PORT_FreeArena(pool, PR_TRUE); return ENOMEM; } + plain.data = payload; + plain.len = payload_len; +#if 0 + if (NSS_CMSContentInfo_SetContent(msg, info, encapsulated_type_tag, + &plain) != SECSuccess) { + PORT_FreeArena(pool, PR_TRUE); + return ENOMEM; + } +#else if (NSS_CMSContentInfo_SetContent_Data(msg, info, &plain, PR_FALSE) != SECSuccess) { PORT_FreeArena(pool, PR_TRUE); return ENOMEM; } +#endif /* Encode and export. */ memset(&encoded, 0, sizeof(encoded)); if (NSS_CMSDEREncode(msg, NULL, &encoded, pool) != SECSuccess) { PORT_FreeArena(pool, PR_TRUE); + pkiDebug("%s: error encoding signed data\n", + __FUNCTION__); return ENOMEM; } if (secitem_to_buf_len(&encoded, signed_data, signed_data_len) != 0) { -- 1.7.6.4