📄 oldfunc.c
字号:
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- *//* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Netscape security libraries. * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1994-2000 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */#include "oldfunc.h"#include "newproto.h"#include "messages.h"/* * All possible key size choices. */static SECKeySizeChoiceInfo SECKeySizeChoiceList[] = { { NULL, 2048, 0 }, { NULL, 1024, 1 }, { NULL, 512, 1 }, { NULL, 0, 0 }};DERTemplate CERTSubjectPublicKeyInfoTemplate[] = { { DER_SEQUENCE, 0, NULL, sizeof(CERTSubjectPublicKeyInfo) }, { DER_INLINE, offsetof(CERTSubjectPublicKeyInfo,algorithm), SECAlgorithmIDTemplate, }, { DER_BIT_STRING, offsetof(CERTSubjectPublicKeyInfo,subjectPublicKey), }, { 0, }};DERTemplate CERTPublicKeyAndChallengeTemplate[] ={ { DER_SEQUENCE, 0, NULL, sizeof(CERTPublicKeyAndChallenge) }, { DER_ANY, offsetof(CERTPublicKeyAndChallenge,spki), }, { DER_IA5_STRING, offsetof(CERTPublicKeyAndChallenge,challenge), }, { 0, }};typedef struct { SSMControlConnection * ctrl; CERTCertificate * cert; CERTDERCerts * derCerts;} caImportCertArg;/* Used for accepting CA certificate. */static PRBool acceptssl, acceptmime, acceptobjectsign, acceptcacert;static char *nickFmt=NULL, *nickFmtWithNum = NULL; static int pqg_prime_bits(char *str);static PQGParams * decode_pqg_params(char *str);static char * GenKey(SSMControlConnection * ctrl, int keysize, char *challenge, PRUint32 type, PQGParams *pqg, PK11SlotInfo * slot);static PRBool certificate_conflict(void * cx, SECItem * derCert, CERTCertDBHandle * handle);static SSMStatus handle_user_cert(SSMControlConnection * ctrl, CERTCertificate *cert, CERTDERCerts *derCerts);static SSMStatus handle_ca_cert(SSMControlConnection * ctrl, CERTCertificate *cert, CERTDERCerts *derCerts);static SSMStatus handle_email_cert(SSMControlConnection * ctrl, CERTCertificate * cert, CERTDERCerts * derCerts);static void SSM_ImportCACert(void * arg);static int init = 0;SSMStatus SSM_EnableHighGradeKeyGen(void){ SECKeySizeChoiceList[0].enabled = 1; return SSM_SUCCESS;}PRBool SSM_KeyGenAllowedForSize(int size){ int i; int numChoices = sizeof(SECKeySizeChoiceList)/sizeof(SECKeySizeChoiceInfo); for (i=0; i<numChoices; i++) { if (SECKeySizeChoiceList[i].size == size && SECKeySizeChoiceList[i].enabled) { return PR_TRUE; } } return PR_FALSE;}SSMStatus InitChoiceList(void) { SSMTextGenContext *cx; if (SSMTextGen_NewTopLevelContext(NULL, &cx) != SSM_SUCCESS) { goto loser; } if (SSM_GetUTF8Text(cx, "high_grade", &SECKeySizeChoiceList[0].name) != SSM_SUCCESS) { goto loser; } if (SSM_GetUTF8Text(cx, "medium_grade", &SECKeySizeChoiceList[1].name) != SSM_SUCCESS) { goto loser; } if (SSM_GetUTF8Text(cx, "low_grade", &SECKeySizeChoiceList[2].name) != SSM_SUCCESS) { goto loser; } SSMTextGen_DestroyContext(cx); return SSM_SUCCESS; loser: if (cx != NULL) { SSMTextGen_DestroyContext(cx); } return SSM_FAILURE;}char ** SSM_GetKeyChoiceList(char * type, char * pqgString, int *nchoices){ char ** list, *pqg, *end; int i, j, len, primeBits; SSMStatus rv; if (!init) { rv = InitChoiceList(); if (rv != SSM_SUCCESS) { PR_ASSERT(!"Could not initialize the choice list for key gen layout!!"); return NULL; } init = 1; } len = sizeof (SECKeySizeChoiceList) / sizeof (SECKeySizeChoiceInfo); list = SSM_ZNEW_ARRAY(char*, len); if (type && (PORT_Strcasecmp(type, "dsa") == 0)) { if (pqgString == NULL) { list[0] = NULL; return list; } pqg = pqgString; j = 0; do { end = PORT_Strchr(pqg, ','); if (end != NULL) *end = '\0'; primeBits = pqg_prime_bits(pqg); for (i = 0; SECKeySizeChoiceList[i].size != 0; i++) { if (SECKeySizeChoiceList[i].size == primeBits) { list[j++] = strdup(SECKeySizeChoiceList[i].name); break; } } pqg = end + 1; } while (end != NULL); } else { int maxKeyBits = SSM_MAX_KEY_BITS; j = 0; for (i = (policyType == ssmDomestic) ? 0 : 1; SECKeySizeChoiceList[i].size != 0; i++) { if (SECKeySizeChoiceList[i].size <= maxKeyBits) list[j++] = strdup(SECKeySizeChoiceList[i].name); } } if (pqgString != NULL) PORT_Free(pqgString); *nchoices = j; return list;}char * SSMControlConnection_GenerateKeyOldStyle(SSMControlConnection * ctrl, char *choiceString, char *challenge, char *typeString, char *pqgString){ SECKeySizeChoiceInfo *choice = SECKeySizeChoiceList; char *end, *str; PQGParams *pqg = NULL; int primeBits; KeyType type; char * keystring = NULL; PK11SlotInfo *slot; SSMKeyGenContext * ct = NULL; SSMKeyGenContextCreateArg arg; PRUint32 keyGenMechanism; SSMStatus rv; while (PORT_Strcmp(choice->name, choiceString) != 0) choice++; if (PORT_Strcmp(challenge, "null") == 0) { PR_Free(challenge); challenge = NULL; } if ((PORT_Strcmp(typeString, "null") == 0) || (PORT_Strcasecmp(typeString, "rsa") == 0)) { type = rsaKey; keyGenMechanism = CKM_RSA_PKCS_KEY_PAIR_GEN; } else if (PORT_Strcasecmp(typeString, "dsa") == 0) { type = dsaKey; keyGenMechanism = CKM_DSA_KEY_PAIR_GEN; if (PORT_Strcmp(pqgString, "null") == 0) goto loser; str = pqgString; do { end = PORT_Strchr(str, ','); if (end != NULL) *end = '\0'; primeBits = pqg_prime_bits(str); if (choice->size == primeBits) goto found_match; str = end + 1; } while (end != NULL); goto loser;found_match: pqg = decode_pqg_params(str); } else { goto loser; } /* * To get slot we first create a keygen context, and * use its facilities to find a slot for our key generation */ arg.parent = ctrl; arg.type = SSM_OLD_STYLE_KEYGEN; arg.param = NULL; SSM_DEBUG("Creating key gen context.\n"); rv = SSMKeyGenContext_Create(&arg, ctrl, (SSMResource **)&ct); if (rv != PR_SUCCESS) { SSM_DEBUG("Could not create KeyGenContext for oldStyleKeyGen.\n"); goto loser; } rv = SSMKeyGenContext_GetSlot(ct, keyGenMechanism); if (rv != SSM_SUCCESS) goto loser; slot = ct->slot; keystring = GenKey(ctrl,choice->size, challenge, keyGenMechanism, pqg, slot); /* received a Cancel event from UI */ if (ct->m_userCancel) { PR_Free(keystring); keystring = NULL; }loser: if (ct) SSMKeyGenContext_Shutdown((SSMResource *)ct, rv); return keystring; }static PQGParams *decode_pqg_params(char *str){ char *buf; unsigned int len; PRArenaPool *arena; PQGParams *params; SECStatus status; arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (arena == NULL) return NULL; params = (PQGParams *) PORT_ArenaZAlloc(arena, sizeof(PQGParams)); if (params == NULL) goto loser; params->arena = arena; buf = (char *)ATOB_AsciiToData(str, &len); if ((buf == NULL) || (len == 0)) goto loser; status = SEC_ASN1Decode(arena, params, SECKEY_PQGParamsTemplate, buf, len); if (status != SECSuccess) goto loser; return params;loser: if (arena != NULL) PORT_FreeArena(arena, PR_FALSE); return NULL;}static intpqg_prime_bits(char *str){ PQGParams *params = NULL; int primeBits = 0, i; params = decode_pqg_params(str); if (params == NULL) goto done; /* lose */ for (i = 0; params->prime.data[i] == 0; i++) /* empty */; primeBits = (params->prime.len - i) * 8;done: if (params != NULL) PQG_DestroyParams(params); return primeBits;}static char * GenKey(SSMControlConnection * ctrl, int keysize, char *challenge, PRUint32 type, PQGParams *pqg, PK11SlotInfo *slot){ SECKEYPrivateKey *privateKey = NULL; SECKEYPublicKey *publicKey = NULL; CERTSubjectPublicKeyInfo *spkInfo = NULL; PRArenaPool *arena = NULL; SECStatus rv = SECFailure; SECItem spkiItem; SECItem pkacItem; SECItem signedItem; CERTPublicKeyAndChallenge pkac; char *keystring = NULL; CK_MECHANISM_TYPE mechanism = type; PK11RSAGenParams rsaParams; void *params; SECOidTag algTag; arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (arena == NULL) { goto done; } /* * Create a new key pair. */ /* Switch statement goes here for DSA */ switch (mechanism) { case CKM_RSA_PKCS_KEY_PAIR_GEN: rsaParams.keySizeInBits = keysize; rsaParams.pe = 65537L; algTag = SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION; params = &rsaParams; break; case CKM_DSA_KEY_PAIR_GEN: params = pqg; algTag = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST; break; default: goto done; break; } privateKey = PK11_GenerateKeyPair(slot, mechanism, params, &publicKey, PR_TRUE, PR_TRUE, NULL); if (privateKey == NULL) { goto done; } /* just in case we'll need to authenticate to the db */ privateKey->wincx = ctrl; /* * Create a subject public key info from the public key. */ spkInfo = SECKEY_CreateSubjectPublicKeyInfo(publicKey); if ( spkInfo == NULL ) { goto done; } /* * Now DER encode the whole subjectPublicKeyInfo. */ rv=DER_Encode(arena, &spkiItem, CERTSubjectPublicKeyInfoTemplate, spkInfo); if (rv != SECSuccess) { goto done; } /* * set up the PublicKeyAndChallenge data structure, then DER encode it */ pkac.spki = spkiItem;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -