]> git.saurik.com Git - apple/security.git/blobdiff - SecurityTests/cspxutils/genKeyPair/genKeyPair.cpp
Security-57031.1.35.tar.gz
[apple/security.git] / SecurityTests / cspxutils / genKeyPair / genKeyPair.cpp
diff --git a/SecurityTests/cspxutils/genKeyPair/genKeyPair.cpp b/SecurityTests/cspxutils/genKeyPair/genKeyPair.cpp
new file mode 100644 (file)
index 0000000..8d9bba7
--- /dev/null
@@ -0,0 +1,238 @@
+/*
+ * 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;
+}