From be053201996b27f1c58a8d29cf863ac9c2ee1387 Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Thu, 30 Sep 2010 18:07:53 -0400 Subject: [PATCH 035/150] - use pre-built dh parameter sets --- src/plugins/preauth/pkinit/pkinit_crypto_nss.c | 343 +++++++++++++++++++++--- 1 files changed, 302 insertions(+), 41 deletions(-) diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_nss.c b/src/plugins/preauth/pkinit/pkinit_crypto_nss.c index 96ef222..224db2b 100644 --- a/src/plugins/preauth/pkinit/pkinit_crypto_nss.c +++ b/src/plugins/preauth/pkinit/pkinit_crypto_nss.c @@ -41,7 +41,6 @@ #include #include -#include #include #include #include @@ -425,6 +424,298 @@ secitem_from_dh_pubval(PLArenaPool *pool, return 0; } +static struct oakley_group { + int identifier; + unsigned int bits; + char name[32]; + char prime[4096]; /* large enough to hold that prime */ + int generator; + char subprime[4096]; /* large enough to hold its subprime ((p-1)/2) */ +} oakley_groups[] = { + { + 1, 768, + "Oakley MODP Group 1", + "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" + "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" + "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" + "E485B576 625E7EC6 F44C42E9 A63A3620 FFFFFFFF FFFFFFFF", + 2, + "7FFFFFFF FFFFFFFF E487ED51 10B4611A 62633145 C06E0E68" + "94812704 4533E63A 0105DF53 1D89CD91 28A5043C C71A026E" + "F7CA8CD9 E69D218D 98158536 F92F8A1B A7F09AB6 B6A8E122" + "F242DABB 312F3F63 7A262174 D31D1B10 7FFFFFFF FFFFFFFF", + }, + { + 2, 1024, + "Oakley MODP Group 2", + "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" + "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" + "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" + "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" + "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381" + "FFFFFFFF FFFFFFFF", + 2, + "7FFFFFFF FFFFFFFF E487ED51 10B4611A 62633145 C06E0E68" + "94812704 4533E63A 0105DF53 1D89CD91 28A5043C C71A026E" + "F7CA8CD9 E69D218D 98158536 F92F8A1B A7F09AB6 B6A8E122" + "F242DABB 312F3F63 7A262174 D31BF6B5 85FFAE5B 7A035BF6" + "F71C35FD AD44CFD2 D74F9208 BE258FF3 24943328 F67329C0" + "FFFFFFFF FFFFFFFF", + }, + { + 5, 1536, + "Oakley MODP Group 5", + "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" + "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" + "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" + "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" + "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" + "C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" + "83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" + "670C354E 4ABC9804 F1746C08 CA237327 FFFFFFFF FFFFFFFF", + 2, + "7FFFFFFF FFFFFFFF E487ED51 10B4611A 62633145 C06E0E68" + "94812704 4533E63A 0105DF53 1D89CD91 28A5043C C71A026E" + "F7CA8CD9 E69D218D 98158536 F92F8A1B A7F09AB6 B6A8E122" + "F242DABB 312F3F63 7A262174 D31BF6B5 85FFAE5B 7A035BF6" + "F71C35FD AD44CFD2 D74F9208 BE258FF3 24943328 F6722D9E" + "E1003E5C 50B1DF82 CC6D241B 0E2AE9CD 348B1FD4 7E9267AF" + "C1B2AE91 EE51D6CB 0E3179AB 1042A95D CF6A9483 B84B4B36" + "B3861AA7 255E4C02 78BA3604 6511B993 FFFFFFFF FFFFFFFF", + }, + { + 14, 2048, + "Oakley MODP Group 14", + "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" + "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" + "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" + "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" + "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" + "C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" + "83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" + "670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" + "E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" + "DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" + "15728E5A 8AACAA68 FFFFFFFF FFFFFFFF", + 2, + "7FFFFFFF FFFFFFFF E487ED51 10B4611A 62633145 C06E0E68" + "94812704 4533E63A 0105DF53 1D89CD91 28A5043C C71A026E" + "F7CA8CD9 E69D218D 98158536 F92F8A1B A7F09AB6 B6A8E122" + "F242DABB 312F3F63 7A262174 D31BF6B5 85FFAE5B 7A035BF6" + "F71C35FD AD44CFD2 D74F9208 BE258FF3 24943328 F6722D9E" + "E1003E5C 50B1DF82 CC6D241B 0E2AE9CD 348B1FD4 7E9267AF" + "C1B2AE91 EE51D6CB 0E3179AB 1042A95D CF6A9483 B84B4B36" + "B3861AA7 255E4C02 78BA3604 650C10BE 19482F23 171B671D" + "F1CF3B96 0C074301 CD93C1D1 7603D147 DAE2AEF8 37A62964" + "EF15E5FB 4AAC0B8C 1CCAA4BE 754AB572 8AE9130C 4C7D0288" + "0AB9472D 45565534 7FFFFFFF FFFFFFFF", + }, + { + 15, 3072, + "Oakley MODP Group 15", + "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" + "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" + "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" + "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" + "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" + "C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" + "83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" + "670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" + "E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" + "DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" + "15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64" + "ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7" + "ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B" + "F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C" + "BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31" + "43DB5BFC E0FD108E 4B82D120 A93AD2CA FFFFFFFF FFFFFFFF", + 2, + "7FFFFFFF FFFFFFFF E487ED51 10B4611A 62633145 C06E0E68" + "94812704 4533E63A 0105DF53 1D89CD91 28A5043C C71A026E" + "F7CA8CD9 E69D218D 98158536 F92F8A1B A7F09AB6 B6A8E122" + "F242DABB 312F3F63 7A262174 D31BF6B5 85FFAE5B 7A035BF6" + "F71C35FD AD44CFD2 D74F9208 BE258FF3 24943328 F6722D9E" + "E1003E5C 50B1DF82 CC6D241B 0E2AE9CD 348B1FD4 7E9267AF" + "C1B2AE91 EE51D6CB 0E3179AB 1042A95D CF6A9483 B84B4B36" + "B3861AA7 255E4C02 78BA3604 650C10BE 19482F23 171B671D" + "F1CF3B96 0C074301 CD93C1D1 7603D147 DAE2AEF8 37A62964" + "EF15E5FB 4AAC0B8C 1CCAA4BE 754AB572 8AE9130C 4C7D0288" + "0AB9472D 45556216 D6998B86 82283D19 D42A90D5 EF8E5D32" + "767DC282 2C6DF785 457538AB AE83063E D9CB87C2 D370F263" + "D5FAD746 6D8499EB 8F464A70 2512B0CE E771E913 0D697735" + "F897FD03 6CC50432 6C3B0139 9F643532 290F958C 0BBD9006" + "5DF08BAB BD30AEB6 3B84C460 5D6CA371 047127D0 3A72D598" + "A1EDADFE 707E8847 25C16890 549D6965 7FFFFFFF FFFFFFFF", + }, + { + 16, 4096, + "Oakley MODP Group 16", + "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" + "29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" + "EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" + "E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" + "EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" + "C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" + "83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" + "670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" + "E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" + "DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" + "15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64" + "ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7" + "ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B" + "F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C" + "BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31" + "43DB5BFC E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7" + "88719A10 BDBA5B26 99C32718 6AF4E23C 1A946834 B6150BDA" + "2583E9CA 2AD44CE8 DBBBC2DB 04DE8EF9 2E8EFC14 1FBECAA6" + "287C5947 4E6BC05D 99B2964F A090C3A2 233BA186 515BE7ED" + "1F612970 CEE2D7AF B81BDD76 2170481C D0069127 D5B05AA9" + "93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34063199" + "FFFFFFFF FFFFFFFF", + 2, + "7FFFFFFF FFFFFFFF E487ED51 10B4611A 62633145 C06E0E68" + "94812704 4533E63A 0105DF53 1D89CD91 28A5043C C71A026E" + "F7CA8CD9 E69D218D 98158536 F92F8A1B A7F09AB6 B6A8E122" + "F242DABB 312F3F63 7A262174 D31BF6B5 85FFAE5B 7A035BF6" + "F71C35FD AD44CFD2 D74F9208 BE258FF3 24943328 F6722D9E" + "E1003E5C 50B1DF82 CC6D241B 0E2AE9CD 348B1FD4 7E9267AF" + "C1B2AE91 EE51D6CB 0E3179AB 1042A95D CF6A9483 B84B4B36" + "B3861AA7 255E4C02 78BA3604 650C10BE 19482F23 171B671D" + "F1CF3B96 0C074301 CD93C1D1 7603D147 DAE2AEF8 37A62964" + "EF15E5FB 4AAC0B8C 1CCAA4BE 754AB572 8AE9130C 4C7D0288" + "0AB9472D 45556216 D6998B86 82283D19 D42A90D5 EF8E5D32" + "767DC282 2C6DF785 457538AB AE83063E D9CB87C2 D370F263" + "D5FAD746 6D8499EB 8F464A70 2512B0CE E771E913 0D697735" + "F897FD03 6CC50432 6C3B0139 9F643532 290F958C 0BBD9006" + "5DF08BAB BD30AEB6 3B84C460 5D6CA371 047127D0 3A72D598" + "A1EDADFE 707E8847 25C16890 54908400 8D391E09 53C3F36B" + "C438CD08 5EDD2D93 4CE1938C 357A711E 0D4A341A 5B0A85ED" + "12C1F4E5 156A2674 6DDDE16D 826F477C 97477E0A 0FDF6553" + "143E2CA3 A735E02E CCD94B27 D04861D1 119DD0C3 28ADF3F6" + "8FB094B8 67716BD7 DC0DEEBB 10B8240E 68034893 EAD82D54" + "C9DA754C 46C7EEE0 C37FDBEE 48536047 A6FA1AE4 9A0318CC" + "FFFFFFFF FFFFFFFF", + } +}; + +static SECItem * +hex_to_secitem(const char *hex, SECItem *item) +{ + int count, i; + unsigned int j; + unsigned char c, acc; + + j = 0; + c = hex[0]; + if ((c == '8') || + (c == '9') || + ((c >= 'a') && (c <= 'f')) || + ((c >= 'A') && (c <= 'F'))) { + item->data[j] = 0; + j++; + } + count = 0; + acc = 0; + for (i = 0; hex[i] != '\0'; i++) { + if ((count % 2) == 0) { + acc = 0; + } + c = hex[i]; + if ((c >= '0') && (c <= '9')) { + acc = (acc << 4) | (c - '0'); + } else + if ((c >= 'a') && (c <= 'f')) { + acc = (acc << 4) | (c - 'a' + 10); + } else + if ((c >= 'A') && (c <= 'F')) { + acc = (acc << 4) | (c - 'A' + 10); + } else { + continue; + } + count++; + if ((count % 2) == 0) { + item->data[j] = acc & 0xff; + acc = 0; + j++; + } + if (j >= item->len) { + /* overrun */ + return NULL; + break; + } + } + if (hex[i] != '\0') { + /* unused bytes */ + return NULL; + } + item->len = j; + return item; +} + +static int +oakley_parse_group(PLArenaPool *pool, struct oakley_group *group, + struct domain_parameters **domain_params) +{ + unsigned int bytes; + struct domain_parameters *params; + SECItem *t; + + params = PORT_ArenaZAlloc(pool, sizeof(*params)); + if (params == NULL) { + return ENOMEM; + } + + /* Allocate more memory than we'll probably need. */ + bytes = group->bits; + + /* Encode the prime (p). */ + t = SECITEM_AllocItem(pool, NULL, bytes); + if (t == NULL) { + return ENOMEM; + } + if (hex_to_secitem(group->prime, t) != t) { + return ENOMEM; + } + params->p = *t; + /* FIXME: this assumes that the generator fits in a long. */ + if (SEC_ASN1EncodeInteger(pool, ¶ms->g, + group->generator) != ¶ms->g) { + return ENOMEM; + } + /* Encode the subprime. */ + t = SECITEM_AllocItem(pool, NULL, bytes); + if (t == NULL) { + return ENOMEM; + } + if (hex_to_secitem(group->subprime, t) != t) { + return ENOMEM; + } + params->q = *t; + *domain_params = params; + return 0; +} + +static struct domain_parameters * +oakley_get_group(PLArenaPool *pool, unsigned int minimum_prime_size) +{ + unsigned int i; + struct domain_parameters *params; + + params = PORT_ArenaZAlloc(pool, sizeof(*params)); + if (params == NULL) { + return NULL; + } + for (i = 0; i < sizeof(oakley_groups) / sizeof(oakley_groups[0]); i++) { + if (oakley_groups[i].bits >= minimum_prime_size) { + if (oakley_parse_group(pool, &oakley_groups[i], + ¶ms) == 0) { + return params; + } + } + } + return NULL; +} + /* Create DH parameters to be sent to the KDC. On success, dh_params should * contain an encoded DomainParameters structure (per RFC3280, the "parameters" * in an AlgorithmIdentifier), and dh_pubkey should contain the public value @@ -447,12 +738,8 @@ client_create_dh(krb5_context context, SECKEYPrivateKey *priv; SECKEYPublicKey *pub; SECKEYDHParams dh_param; - SECStatus status; - PQGParams *pqg_params; - PQGVerify *pqg_verify; - struct domain_parameters params; + struct domain_parameters *params; SECItem encoded; - int pqg_size; pool = PORT_NewArena(sizeof(double)); if (pool == NULL) { @@ -460,42 +747,23 @@ client_create_dh(krb5_context context, } memset(¶ms, 0, sizeof(params)); - /* Generate domain parameters. The size parameter we pass in will - * eventually be fed into PQG_INDEX_TO_PBITS (see blapit.h) to - * determine the number of bits. */ - pqg_size = ((dh_size_bits > 512) ? (dh_size_bits - 512) : 0) / 64; - if (pqg_size > 8) { - pqg_size = 8; /* FIXME: this is as high as NSS will accept */ - } - memset(&pqg_params, 0, sizeof(pqg_params)); - memset(&pqg_verify, 0, sizeof(pqg_verify)); - if (PK11_PQG_ParamGen(pqg_size, &pqg_params, - &pqg_verify) != SECSuccess) { - PORT_FreeArena(pool, PR_TRUE); - pkiDebug("%s: error generating parameters\n", __FUNCTION__); - return ENOMEM; - } - if ((PK11_PQG_VerifyParams(pqg_params, pqg_verify, - &status) != SECSuccess) || - (status != SECSuccess)) { - PK11_PQG_DestroyParams(pqg_params); - PK11_PQG_DestroyVerify(pqg_verify); - PORT_FreeArena(pool, PR_TRUE); - pkiDebug("%s: error verifying parameters\n", __FUNCTION__); - return ENOMEM; + /* Find suitable domain parameters. */ + params = oakley_get_group(pool, dh_size_bits); + if (params == NULL) { + pkiDebug("%s: error finding suitable parameters\n", + __FUNCTION__); + return ENOENT; } - PK11_PQG_DestroyVerify(pqg_verify); /* Set up to generate the public key. */ memset(&dh_param, 0, sizeof(dh_param)); dh_param.arena = pool; - dh_param.prime = pqg_params->prime; - dh_param.base = pqg_params->base; + dh_param.prime = params->p; + dh_param.base = params->g; /* Generate a public value and a private key. */ slot = PK11_GetBestSlot(CKM_DH_PKCS_KEY_PAIR_GEN, NULLCX); if (slot == NULL) { - PK11_PQG_DestroyParams(pqg_params); PORT_FreeArena(pool, PR_TRUE); pkiDebug("%s: error selecting slot\n", __FUNCTION__); return ENOMEM; @@ -506,14 +774,10 @@ client_create_dh(krb5_context context, NULLCX); /* Finish building the return values. */ - params.p = pqg_params->prime; - params.g = pqg_params->base; - params.q = pqg_params->subPrime; memset(&encoded, 0, sizeof(encoded)); - if (SEC_ASN1EncodeItem(pool, &encoded, ¶ms, + if (SEC_ASN1EncodeItem(pool, &encoded, params, domain_parameters_template) != &encoded) { PK11_FreeSlot(slot); - PK11_PQG_DestroyParams(pqg_params); PORT_FreeArena(pool, PR_TRUE); pkiDebug("%s: error encoding parameters\n", __FUNCTION__); return ENOMEM; @@ -522,7 +786,6 @@ client_create_dh(krb5_context context, /* Export the return values. */ if (secitem_to_buf_len(&encoded, dh_params, dh_params_len) != 0) { PK11_FreeSlot(slot); - PK11_PQG_DestroyParams(pqg_params); PORT_FreeArena(pool, PR_TRUE); return ENOMEM; } @@ -531,14 +794,12 @@ client_create_dh(krb5_context context, free(*dh_params); *dh_params = NULL; PK11_FreeSlot(slot); - PK11_PQG_DestroyParams(pqg_params); PORT_FreeArena(pool, PR_TRUE); return ENOMEM; } /* Save our private key for reuse later. */ SECKEY_DestroyPublicKey(pub); - PK11_PQG_DestroyParams(pqg_params); if (req_cryptoctx->client_dh_key != NULL) { SECKEY_DestroyPrivateKey(req_cryptoctx->client_dh_key); } -- 1.7.6.4