+++ /dev/null
-/*
- * genKeyPair.cpp - create a key pair, store in specified keychain
- */
-#include <stdlib.h>
-#include <stdio.h>
-#include <time.h>
-#include <string.h>
-#include <unistd.h>
-#include <Security/Security.h>
-#include "cspwrap.h"
-#include "common.h"
-
-static void usage(char **argv)
-{
- printf("usage: %s keychain [options]\n", argv[0]);
- printf("Options:\n");
- printf(" -l label -- no default\n");
- printf(" -a r|f|d -- algorithm RSA/FEE/DSA, default = RSA\n");
- printf(" -k bits -- key size in bits, default is 1024/128/512 for RSA/FEE/DSA\n");
- exit(1);
-}
-
-/*
- * Generate key pair of arbitrary algorithm.
- * FEE keys will have random private data.
- * Like the cspGenKeyPair() in cspwrap.c except this provides a DLDB handle.
- */
-static CSSM_RETURN genKeyPair(CSSM_CSP_HANDLE cspHand,
- CSSM_DL_DB_HANDLE dlDbHand,
- uint32 algorithm,
- const char *keyLabel,
- unsigned keyLabelLen,
- uint32 keySize, // in bits
- CSSM_KEY_PTR pubKey, // mallocd by caller
- uint32 pubKeyUsage, // CSSM_KEYUSE_ENCRYPT, etc.
- CSSM_KEY_PTR privKey, // mallocd by caller
- uint32 privKeyUsage) // CSSM_KEYUSE_DECRYPT, etc.
-{
- CSSM_RETURN crtn;
- CSSM_CC_HANDLE ccHand;
- CSSM_DATA keyLabelData;
- uint32 pubAttr;
- uint32 privAttr;
- CSSM_RETURN ocrtn = CSSM_OK;
-
- /* pre-context-create algorithm-specific stuff */
- switch(algorithm) {
- case CSSM_ALGID_FEE:
- if(keySize == CSP_KEY_SIZE_DEFAULT) {
- keySize = CSP_FEE_KEY_SIZE_DEFAULT;
- }
- break;
- case CSSM_ALGID_RSA:
- if(keySize == CSP_KEY_SIZE_DEFAULT) {
- keySize = CSP_RSA_KEY_SIZE_DEFAULT;
- }
- break;
- case CSSM_ALGID_DSA:
- if(keySize == CSP_KEY_SIZE_DEFAULT) {
- keySize = CSP_DSA_KEY_SIZE_DEFAULT;
- }
- break;
- default:
- printf("cspGenKeyPair: Unknown algorithm\n");
- break;
- }
- 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) {
- printError("CSSM_CSP_CreateKeyGenContext", crtn);
- ocrtn = crtn;
- goto abort;
- }
- /* cook up attribute bits */
- pubAttr = CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_EXTRACTABLE | CSSM_KEYATTR_PERMANENT;
- privAttr = CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_EXTRACTABLE | CSSM_KEYATTR_PERMANENT;
-
- /* post-context-create algorithm-specific stuff */
- switch(algorithm) {
- 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) {
- printError("CSSM_GenerateAlgorithmParams", crtn);
- return crtn;
- }
- appFreeCssmData(&dummy, CSSM_FALSE);
- }
- break;
- default:
- break;
- }
-
- /* add in DL/DB to context */
- crtn = cspAddDlDbToContext(ccHand, dlDbHand.DLHandle, dlDbHand.DBHandle);
- if(crtn) {
- ocrtn = crtn;
- goto abort;
- }
-
- crtn = CSSM_GenerateKeyPair(ccHand,
- pubKeyUsage,
- pubAttr,
- &keyLabelData,
- pubKey,
- privKeyUsage,
- privAttr,
- &keyLabelData, // same labels
- NULL, // CredAndAclEntry
- privKey);
- if(crtn) {
- printError("CSSM_GenerateKeyPair", crtn);
- ocrtn = crtn;
- goto abort;
- }
-abort:
- if(ccHand != 0) {
- crtn = CSSM_DeleteContext(ccHand);
- if(crtn) {
- printError("CSSM_DeleteContext", crtn);
- ocrtn = CSSM_ERRCODE_INTERNAL_ERROR;
- }
- }
- return ocrtn;
-}
-
-int main(int argc, char **argv)
-{
- char *kcName = NULL;
- char *label = NULL;
- CSSM_ALGORITHMS keyAlg = CSSM_ALGID_RSA;
- unsigned keySizeInBits = CSP_KEY_SIZE_DEFAULT;
-
- if(argc < 2) {
- usage(argv);
- }
- kcName = argv[1];
-
- extern char *optarg;
- extern int optind;
-
- optind = 2;
- int arg;
- while ((arg = getopt(argc, argv, "l:a:k:h")) != -1) {
- switch (arg) {
- case 'l':
- label = optarg;
- break;
- case 'a':
- switch(optarg[0]) {
- case 'r':
- keyAlg = CSSM_ALGID_RSA;
- break;
- case 'f':
- keyAlg = CSSM_ALGID_FEE;
- break;
- case 'd':
- keyAlg = CSSM_ALGID_DSA;
- break;
- default:
- usage(argv);
- }
- break;
- case 'k':
- keySizeInBits = atoi(optarg);
- break;
- default:
- usage(argv);
- }
- }
- if(optind != argc) {
- usage(argv);
- }
-
- SecKeychainRef kcRef = nil;
- OSStatus ortn;
-
- ortn = SecKeychainOpen(kcName, &kcRef);
- if(ortn) {
- cssmPerror("SecKeychainOpen", ortn);
- exit(1);
- }
-
- CSSM_CSP_HANDLE cspHand = 0;
- CSSM_DL_DB_HANDLE dlDbHand = {0, 0};
- ortn = SecKeychainGetCSPHandle(kcRef, &cspHand);
- if(ortn) {
- cssmPerror("SecKeychainGetCSPHandle", ortn);
- exit(1);
- }
- ortn = SecKeychainGetDLDBHandle(kcRef, &dlDbHand);
- if(ortn) {
- cssmPerror("SecKeychainGetDLDBHandle", ortn);
- exit(1);
- }
-
- CSSM_KEY privKey;
- CSSM_KEY pubKey;
- CSSM_RETURN crtn;
-
- crtn = genKeyPair(cspHand, dlDbHand,
- keyAlg,
- label, (label ? strlen(label) : 0),
- keySizeInBits,
- &pubKey,
- CSSM_KEYUSE_ANY, // may want to parameterize
- &privKey,
- CSSM_KEYUSE_ANY); // may want to parameterize
- if(crtn) {
- printf("**Error creating key pair.\n");
- }
- else {
- printf("...key pair created in keychain %s.\n", kcName);
- }
-
- cspFreeKey(cspHand, &privKey);
- cspFreeKey(cspHand, &pubKey);
- CFRelease(kcRef);
- return 0;
-}