/* * Generate a Diffie-Hellman key pair. Algorithm parameters are * either specified by caller via inParams, or are generated here * and returned to caller in outParams. Exactly one of (inParams, * outParams) must be non-NULL. */ CSSM_RETURN cdsaDhGenerateKeyPair( CSSM_CSP_HANDLE cspHandle, CSSM_KEY_PTR publicKey, CSSM_KEY_PTR privateKey, uint32 keySizeInBits, const CSSM_DATA *inParams, // optional CSSM_DATA_PTR outParams) // optional, we malloc { CSSM_RETURN crtn; CSSM_CC_HANDLE ccHandle; CSSM_DATA labelData = {8, (uint8 *)"tempKey"}; /* Caller must specify either inParams or outParams, not both */ if(inParams && outParams) { return CSSMERR_CSSM_INVALID_POINTER; } if(!inParams && !outParams) { return CSSMERR_CSSM_INVALID_POINTER; } memset(publicKey, 0, sizeof(CSSM_KEY)); memset(privateKey, 0, sizeof(CSSM_KEY)); crtn = CSSM_CSP_CreateKeyGenContext(cspHandle, CSSM_ALGID_DH, keySizeInBits, NULL, // Seed NULL, // Salt NULL, // StartDate NULL, // EndDate inParams, // Params, may be NULL &ccHandle); if(crtn) { return crtn; } if(outParams) { /* explicitly generate params and return them to caller */ outParams->Data = NULL; outParams->Length = 0; crtn = CSSM_GenerateAlgorithmParams(ccHandle, keySizeInBits, outParams); if(crtn) { CSSM_DeleteContext(ccHandle); return crtn; } } crtn = CSSM_GenerateKeyPair(ccHandle, CSSM_KEYUSE_DERIVE, // only legal use of a Diffie-Hellman key CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE, &labelData, publicKey, /* private key specification */ CSSM_KEYUSE_DERIVE, CSSM_KEYATTR_RETURN_REF, &labelData, // same labels NULL, // CredAndAclEntry privateKey); CSSM_DeleteContext(ccHandle); return crtn; }
CSSM_RETURN cuCspGenKeyPair(CSSM_CSP_HANDLE cspHand, CSSM_DL_DB_HANDLE *dlDbHand, // optional uint32 algorithm, const char *keyLabel, unsigned keyLabelLen, uint32 keySize, // in bits CSSM_KEY_PTR pubKey, // mallocd by caller CSSM_KEYUSE pubKeyUsage, // CSSM_KEYUSE_ENCRYPT, etc. CSSM_KEYATTR_FLAGS pubAttrs, // CSSM_KEYATTR_EXTRACTABLE, etc. CSSM_KEY_PTR privKey, // mallocd by caller CSSM_KEYUSE privKeyUsage, // CSSM_KEYUSE_DECRYPT, etc. CSSM_KEYATTR_FLAGS privAttrs) // CSSM_KEYATTR_EXTRACTABLE, etc. { CSSM_RETURN crtn; CSSM_RETURN ocrtn; CSSM_CC_HANDLE ccHand; CSSM_DATA keyLabelData; keyLabelData.Data = (uint8 *)keyLabel, keyLabelData.Length = keyLabelLen; memset(pubKey, 0, sizeof(CSSM_KEY)); memset(privKey, 0, sizeof(CSSM_KEY)); crtn = CSSM_CSP_CreateKeyGenContext(cspHand, algorithm, keySize, NULL, // Seed NULL, // Salt NULL, // StartDate NULL, // EndDate NULL, // Params &ccHand); if(crtn) { cuPrintError("CSSM_CSP_CreateKeyGenContext", crtn); return crtn; } /* post-context-create algorithm-specific stuff */ switch(algorithm) { #if DO_DSA_GEN_PARAMS case CSSM_ALGID_DSA: /* * extra step - generate params - this just adds some * info to the context */ { CSSM_DATA dummy = {0, NULL}; crtn = CSSM_GenerateAlgorithmParams(ccHand, keySize, &dummy); if(crtn) { cuPrintError("CSSM_GenerateAlgorithmParams", crtn); CSSM_DeleteContext(ccHand); return crtn; } cuAppFree(dummy.Data, NULL); } break; #endif /* DO_DSA_GEN_PARAMS */ default: break; } /* optionally specify DL/DB storage location */ if(dlDbHand) { crtn = cuAddContextAttribute(ccHand, CSSM_ATTRIBUTE_DL_DB_HANDLE, sizeof(CSSM_ATTRIBUTE_DL_DB_HANDLE), dlDbHand); if(crtn) { CSSM_DeleteContext(ccHand); return crtn; } } ocrtn = CSSM_GenerateKeyPair(ccHand, pubKeyUsage, pubAttrs, &keyLabelData, pubKey, privKeyUsage, privAttrs, &keyLabelData, // same labels NULL, // CredAndAclEntry privKey); if(ocrtn) { cuPrintError("CSSM_GenerateKeyPair", ocrtn); } crtn = CSSM_DeleteContext(ccHand); if(crtn) { cuPrintError("CSSM_DeleteContext", crtn); if(ocrtn == CSSM_OK) { /* error on CSSM_GenerateKeyPair takes precedence */ ocrtn = crtn; } } return ocrtn; }
/* * Generate asymmetric key pair. Currently supported algorithms * are RSA, DSA, and FEE. */ CSSM_RETURN cdsaGenerateKeyPair( CSSM_CSP_HANDLE cspHandle, CSSM_ALGORITHMS keyAlg, // e.g., CSSM_ALGID_RSA uint32 keySizeInBits, CSSM_KEY_PTR publicKey, CSSM_KEY_PTR privateKey) { CSSM_RETURN crtn; CSSM_CC_HANDLE ccHandle; CSSM_DATA dummyLabel = {8, (uint8 *)"tempKey"}; memset(publicKey, 0, sizeof(CSSM_KEY)); memset(privateKey, 0, sizeof(CSSM_KEY)); crtn = CSSM_CSP_CreateKeyGenContext(cspHandle, keyAlg, keySizeInBits, NULL, // Seed NULL, // Salt NULL, // StartDate NULL, // EndDate NULL, // Params &ccHandle); if(crtn) { return crtn; } /* post-context-create algorithm-specific stuff */ switch(keyAlg) { case CSSM_ALGID_DSA: /* * extra step - generate params - this just adds some * info to the context */ { CSSM_DATA dummy = {0, NULL}; crtn = CSSM_GenerateAlgorithmParams(ccHandle, keySizeInBits, &dummy); if(crtn) { return crtn; } free(dummy.Data); } break; default: /* RSA, FEE - nothing to do */ break; } /* * Public keys can encrypt and verify signature. * Private keys can decrypt and sign. */ crtn = CSSM_GenerateKeyPair(ccHandle, CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_VERIFY, CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE, &dummyLabel, publicKey, CSSM_KEYUSE_DECRYPT | CSSM_KEYUSE_SIGN, CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE, &dummyLabel, // same labels NULL, // CredAndAclEntry privateKey); CSSM_DeleteContext(ccHandle); return crtn; }
/* * Generate DSA key pair. Algorithm parameters are * either specified by caller via inParams, or are generated here * and returned to caller in outParams. Exactly one of (inParams, * outParams) must be non-NULL. */ static CSSM_RETURN genDsaKeyPair( CSSM_CSP_HANDLE cspHand, const char *keyLabel, unsigned keyLabelLen, uint32 keySize, // in bits CSSM_KEY_PTR pubKey, // mallocd by caller CSSM_BOOL pubIsRef, // true - reference key, false - data uint32 pubKeyUsage, // CSSM_KEYUSE_ENCRYPT, etc. CSSM_KEYBLOB_FORMAT pubFormat, // Optional. Some algorithms (currently, FEE) // provide for multiple key blob formats. // Specify 0 or CSSM_KEYBLOB_RAW_FORMAT_NONE // to get the default format. CSSM_KEY_PTR privKey, // mallocd by caller CSSM_BOOL privIsRef, // true - reference key, false - data uint32 privKeyUsage, // CSSM_KEYUSE_DECRYPT, etc. CSSM_KEYBLOB_FORMAT privFormat, // optional 0 ==> default const CSSM_DATA *inParams, // optional CSSM_DATA_PTR outParams) // optional, we malloc { CSSM_RETURN crtn; CSSM_CC_HANDLE ccHand; CSSM_DATA keyLabelData; uint32 pubAttr; uint32 privAttr; CSSM_RETURN ocrtn = CSSM_OK; /* Caller must specify either inParams or outParams, not both */ if(inParams && outParams) { return CSSMERR_CSSM_INVALID_POINTER; } if(!inParams && !outParams) { return CSSMERR_CSSM_INVALID_POINTER; } keyLabelData.Data = (uint8 *)keyLabel, keyLabelData.Length = keyLabelLen; memset(pubKey, 0, sizeof(CSSM_KEY)); memset(privKey, 0, sizeof(CSSM_KEY)); crtn = CSSM_CSP_CreateKeyGenContext(cspHand, CSSM_ALGID_DSA, keySize, NULL, // Seed NULL, // Salt NULL, // StartDate NULL, // EndDate inParams, // Params, may be NULL &ccHand); if(crtn) { printError("CSSM_CSP_CreateKeyGenContext", crtn); return crtn; } /* cook up attribute bits */ if(pubIsRef) { pubAttr = CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_EXTRACTABLE; } else { pubAttr = CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE; } if(privIsRef) { privAttr = CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_EXTRACTABLE; } else { privAttr = CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE; } if(outParams) { /* explicitly generate params and return them to caller */ outParams->Data = NULL; outParams->Length = 0; crtn = CSSM_GenerateAlgorithmParams(ccHand, keySize, outParams); if(crtn) { printError("CSSM_GenerateAlgorithmParams", crtn); CSSM_DeleteContext(ccHand); return crtn; } } /* optional format specifiers */ if(pubFormat != CSSM_KEYBLOB_RAW_FORMAT_NONE) { crtn = AddContextAttribute(ccHand, CSSM_ATTRIBUTE_PUBLIC_KEY_FORMAT, sizeof(uint32), CAT_Uint32, NULL, pubFormat); if(crtn) { printError("AddContextAttribute(CSSM_ATTRIBUTE_PUBLIC_KEY_FORMAT)", crtn); return crtn; } } if(privFormat != CSSM_KEYBLOB_RAW_FORMAT_NONE) { crtn = AddContextAttribute(ccHand, CSSM_ATTRIBUTE_PRIVATE_KEY_FORMAT, sizeof(uint32), CAT_Uint32, NULL, privFormat); if(crtn) { printError("AddContextAttribute(CSSM_ATTRIBUTE_PRIVATE_KEY_FORMAT)", crtn); return crtn; } } crtn = CSSM_GenerateKeyPair(ccHand, pubKeyUsage, pubAttr, &keyLabelData, pubKey, privKeyUsage, privAttr, &keyLabelData, // same labels NULL, // CredAndAclEntry privKey); if(crtn) { printError("CSSM_GenerateKeyPair", crtn); ocrtn = crtn; } if(ccHand != 0) { crtn = CSSM_DeleteContext(ccHand); if(crtn) { printError("CSSM_DeleteContext", crtn); ocrtn = CSSM_ERRCODE_INTERNAL_ERROR; } } return ocrtn; }
/* * Generate key pair of specified alg and raw format. * Alg params are optional, though they are expected to be here * for DH and DSA. */ static CSSM_RETURN genKeyPair( CSSM_CSP_HANDLE cspHand, CSSM_ALGORITHMS keyAlg, uint32 keySize, // in bits CSSM_KEY_PTR pubKey, CSSM_KEYBLOB_FORMAT pubFormat, CSSM_KEY_PTR privKey, CSSM_KEYBLOB_FORMAT privFormat, const CSSM_DATA *inParams) // optional { CSSM_RETURN crtn; CSSM_CC_HANDLE ccHand; CSSM_DATA keyLabelData; CSSM_RETURN ocrtn = CSSM_OK; keyLabelData.Data = (uint8 *)USAGE_NAME, keyLabelData.Length = USAGE_NAME_LEN; memset(pubKey, 0, sizeof(CSSM_KEY)); memset(privKey, 0, sizeof(CSSM_KEY)); crtn = CSSM_CSP_CreateKeyGenContext(cspHand, keyAlg, keySize, NULL, // Seed NULL, // Salt NULL, // StartDate NULL, // EndDate inParams, // Params, may be NULL &ccHand); if(crtn) { printError("CSSM_CSP_CreateKeyGenContext", crtn); return crtn; } /* optional format specifiers */ if(pubFormat != CSSM_KEYBLOB_RAW_FORMAT_NONE) { crtn = AddContextAttribute(ccHand, CSSM_ATTRIBUTE_PUBLIC_KEY_FORMAT, sizeof(uint32), CAT_Uint32, NULL, pubFormat); if(crtn) { printError("AddContextAttribute(" "CSSM_ATTRIBUTE_PUBLIC_KEY_FORMAT)", crtn); return crtn; } } if(privFormat != CSSM_KEYBLOB_RAW_FORMAT_NONE) { crtn = AddContextAttribute(ccHand, CSSM_ATTRIBUTE_PRIVATE_KEY_FORMAT, sizeof(uint32), CAT_Uint32, NULL, privFormat); if(crtn) { printError("AddContextAttribute(" "CSSM_ATTRIBUTE_PRIVATE_KEY_FORMAT)", crtn); return crtn; } } CSSM_KEYATTR_FLAGS attrFlags = CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE; crtn = CSSM_GenerateKeyPair(ccHand, CSSM_KEYUSE_DERIVE, attrFlags, &keyLabelData, pubKey, CSSM_KEYUSE_DERIVE, attrFlags, &keyLabelData, // same labels NULL, // CredAndAclEntry privKey); if(crtn) { printError("CSSM_GenerateKeyPair", crtn); ocrtn = crtn; } if(ccHand != 0) { crtn = CSSM_DeleteContext(ccHand); if(crtn) { printError("CSSM_DeleteContext", crtn); ocrtn = CSSM_ERRCODE_INTERNAL_ERROR; } } return ocrtn; }
/* * Common, flexible, error-tolerant key pair generator. */ static int genKeyPair( CSSM_CSP_HANDLE cspHand, uint32 algorithm, const char *keyAlgStr, uint32 keySizeInBits, CSSM_KEY_PTR pubKey, CSSM_KEYATTR_FLAGS pubKeyAttr, CSSM_KEYUSE pubKeyUsage, CSSM_KEY_PTR privKey, CSSM_KEYATTR_FLAGS privKeyAttr, CSSM_KEYUSE privKeyUsage, CSSM_BOOL quiet, bool setStartDate, int startDeltaDays, bool setEndDate, int endDeltaDays, CSSM_DL_DB_HANDLE *dlDbHand = NULL) // optional { CSSM_RETURN crtn; CSSM_CC_HANDLE ccHand; CSSM_DATE startDate; CSSM_DATE endDate; if(setStartDate) { setDate(startDate, startDeltaDays); } if(setEndDate) { setDate(endDate, endDeltaDays); } memset(pubKey, 0, sizeof(CSSM_KEY)); memset(privKey, 0, sizeof(CSSM_KEY)); crtn = CSSM_CSP_CreateKeyGenContext(cspHand, algorithm, keySizeInBits, NULL, // Seed NULL, // Salt setStartDate ? &startDate : NULL, setEndDate ? &endDate : NULL, NULL, // Params &ccHand); if(crtn) { printError("CSSM_CSP_CreateKeyGenContext", crtn); return testError(quiet); } if(dlDbHand) { /* add in DL/DB to context */ crtn = cspAddDlDbToContext(ccHand, dlDbHand->DLHandle, dlDbHand->DBHandle); if(crtn) { return testError(quiet); } } crtn = CSSM_GenerateKeyPair(ccHand, pubKeyUsage, pubKeyAttr, &keyLabelData, pubKey, privKeyUsage, privKeyAttr, &keyLabelData, // same labels NULL, // CredAndAclEntry privKey); if(crtn) { printError("CSSM_GenerateKeyPair", crtn); return testError(quiet); } CSSM_DeleteContext(ccHand); CSSM_KEYHEADER &pubHdr = pubKey->KeyHeader; CSSM_KEYHEADER &privHdr = privKey->KeyHeader; CSSM_DATE *cdp = NULL; if(setStartDate) { cdp = &startDate; } if(compareDates(cdp, &pubHdr.StartDate, keyAlgStr, quiet)) { return 1; } if(compareDates(cdp, &privHdr.StartDate, keyAlgStr, quiet)) { return 1; } if(setEndDate) { cdp = &endDate; } else { cdp = NULL; } if(compareDates(cdp, &pubHdr.EndDate, keyAlgStr, quiet)) { return 1; } if(compareDates(cdp, &privHdr.EndDate, keyAlgStr, quiet)) { return 1; } return 0; }
/* * Common, flexible, error-tolerant key pair generator. */ static int genKeyPair( CSSM_CSP_HANDLE cspHand, uint32 algorithm, const char *keyAlgStr, uint32 keySizeInBits, CSSM_KEY_PTR pubKey, CSSM_KEYATTR_FLAGS pubKeyAttr, CSSM_KEYUSE pubKeyUsage, CSSM_KEY_PTR privKey, CSSM_KEYATTR_FLAGS privKeyAttr, CSSM_KEYUSE privKeyUsage, CSSM_RETURN expectRtn, CSSM_BOOL quiet, CSSM_BOOL freeKeys, // true: free the keys on exit const char *testStr) { CSSM_RETURN crtn; CSSM_CC_HANDLE ccHand; CSSM_DATA keyLabelData = {4, (uint8 *)"foo"}; int irtn; memset(pubKey, 0, sizeof(CSSM_KEY)); memset(privKey, 0, sizeof(CSSM_KEY)); crtn = CSSM_CSP_CreateKeyGenContext(cspHand, algorithm, keySizeInBits, NULL, // Seed NULL, // Salt NULL, // StartDate NULL, // EndDate NULL, // Params &ccHand); if(crtn) { printError("CSSM_CSP_CreateKeyGenContext", crtn); return testError(quiet); } /* post-context-create algorithm-specific stuff */ switch(algorithm) { case CSSM_ALGID_RSA: break; case CSSM_ALGID_DSA: /* * extra step - generate params - this just adds some * info to the context */ { CSSM_DATA dummy = {0, NULL}; crtn = CSSM_GenerateAlgorithmParams(ccHand, keySizeInBits, &dummy); if(crtn) { printError("CSSM_GenerateAlgorithmParams", crtn); return testError(quiet); } appFreeCssmData(&dummy, CSSM_FALSE); } break; default: break; } crtn = CSSM_GenerateKeyPair(ccHand, pubKeyUsage, pubKeyAttr, &keyLabelData, pubKey, privKeyUsage, privKeyAttr, &keyLabelData, // same labels NULL, // CredAndAclEntry privKey); if(crtn != expectRtn) { printf("***Testing %s for alg %s:\n", testStr, keyAlgStr); printf(" CSSM_GenerateKeyPair: expect %s\n", cssmErrToStr(expectRtn)); printf(" CSSM_GenerateKeyPair: got %s\n", cssmErrToStr(crtn)); irtn = testError(quiet); } else { irtn = 0; } CSSM_DeleteContext(ccHand); if(freeKeys && (crtn == CSSM_OK)) { cspFreeKey(cspHand, pubKey); cspFreeKey(cspHand, privKey); } return irtn; }