]> git.saurik.com Git - apple/security.git/blobdiff - SecurityTests/cspxutils/keyHashAsym/keyHashAsym.c
Security-57031.1.35.tar.gz
[apple/security.git] / SecurityTests / cspxutils / keyHashAsym / keyHashAsym.c
diff --git a/SecurityTests/cspxutils/keyHashAsym/keyHashAsym.c b/SecurityTests/cspxutils/keyHashAsym/keyHashAsym.c
new file mode 100644 (file)
index 0000000..dbdff5e
--- /dev/null
@@ -0,0 +1,547 @@
+/*
+ * keyHashAsym.c - CSSM_APPLECSP_KEYDIGEST passthrough test for all
+ *                                known asymmetric algorithms and key formats
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <string.h>
+#include <Security/cssm.h>
+#include "cspwrap.h"
+#include "common.h"
+#include "cspdlTesting.h"
+#include <security_cdsa_utils/cuFileIo.h>
+
+#define USAGE_NAME                     "noUsage"
+#define USAGE_NAME_LEN         (strlen(USAGE_NAME))
+#define LOOPS_DEF                      10
+
+#define DSA_PARAM_FILE         "dsaParams_512.der"
+#define DH_PARAM_FILE          "dhParams_512.der"
+
+static void usage(char **argv)
+{
+       printf("usage: %s [options]\n", argv[0]);
+       printf("Options:\n");
+       printf("  l=loops (default=%d; 0=forever)\n", LOOPS_DEF);
+       printf("  D (CSP/DL; default = bare CSP)\n");
+       printf("  p(ause on each loop)\n");
+       printf("  q(uiet)\n");
+       printf("  v(erbose))\n");
+       exit(1);
+}
+
+static CSSM_DATA       dsa512Params;
+static CSSM_DATA       dh512Params;
+
+/*
+ * Describe parameters for one test iteration.
+ */
+typedef struct {
+       CSSM_ALGORITHMS         keyAlg;
+       CSSM_KEYBLOB_FORMAT     pubKeyForm;
+       CSSM_KEYBLOB_FORMAT     privKeyForm;
+       uint32                          keySizeInBits;
+       CSSM_DATA                       *algParams;             // optional
+} KeyHashTest;
+
+KeyHashTest KeyHashTestParams[] = 
+{
+       /* RSA */
+       {       CSSM_ALGID_RSA, 
+               CSSM_KEYBLOB_RAW_FORMAT_NONE,   CSSM_KEYBLOB_RAW_FORMAT_NONE,
+               512, NULL
+       },
+       {       CSSM_ALGID_RSA, 
+               CSSM_KEYBLOB_RAW_FORMAT_PKCS1,  CSSM_KEYBLOB_RAW_FORMAT_NONE,
+               512, NULL
+       },
+       {       CSSM_ALGID_RSA, 
+               CSSM_KEYBLOB_RAW_FORMAT_X509,   CSSM_KEYBLOB_RAW_FORMAT_NONE,
+               512, NULL
+       },
+       {       CSSM_ALGID_RSA, 
+               CSSM_KEYBLOB_RAW_FORMAT_NONE,   CSSM_KEYBLOB_RAW_FORMAT_PKCS1,
+               512, NULL
+       },
+       {       CSSM_ALGID_RSA, 
+               CSSM_KEYBLOB_RAW_FORMAT_NONE,   CSSM_KEYBLOB_RAW_FORMAT_PKCS8,
+               512, NULL
+       },
+       
+       /* ECDSA */
+       {       CSSM_ALGID_ECDSA,
+               CSSM_KEYBLOB_RAW_FORMAT_NONE, CSSM_KEYBLOB_RAW_FORMAT_NONE,
+               192, NULL 
+       },
+       {       CSSM_ALGID_ECDSA,
+               CSSM_KEYBLOB_RAW_FORMAT_X509, CSSM_KEYBLOB_RAW_FORMAT_PKCS8,
+               256, NULL 
+       },
+       {       CSSM_ALGID_ECDSA,
+               CSSM_KEYBLOB_RAW_FORMAT_NONE, CSSM_KEYBLOB_RAW_FORMAT_PKCS8,
+               384, NULL 
+       },
+       {       CSSM_ALGID_ECDSA,
+               CSSM_KEYBLOB_RAW_FORMAT_X509, CSSM_KEYBLOB_RAW_FORMAT_PKCS8,
+               521, NULL 
+       },
+
+       /* DSA */
+       {       CSSM_ALGID_DSA, 
+               CSSM_KEYBLOB_RAW_FORMAT_NONE,   CSSM_KEYBLOB_RAW_FORMAT_NONE,
+               512, &dsa512Params
+       },
+       {       CSSM_ALGID_DSA, 
+               CSSM_KEYBLOB_RAW_FORMAT_FIPS186,        CSSM_KEYBLOB_RAW_FORMAT_NONE,
+               512, &dsa512Params
+       },
+       {       CSSM_ALGID_DSA, 
+               CSSM_KEYBLOB_RAW_FORMAT_X509,   CSSM_KEYBLOB_RAW_FORMAT_NONE,
+               512, &dsa512Params
+       },
+       {       CSSM_ALGID_DSA, 
+               CSSM_KEYBLOB_RAW_FORMAT_NONE,   CSSM_KEYBLOB_RAW_FORMAT_FIPS186,
+               512, &dsa512Params
+       },
+       {       CSSM_ALGID_DSA, 
+               CSSM_KEYBLOB_RAW_FORMAT_NONE,   CSSM_KEYBLOB_RAW_FORMAT_OPENSSL,
+               512, &dsa512Params
+       },
+       {       CSSM_ALGID_DSA, 
+               CSSM_KEYBLOB_RAW_FORMAT_NONE,   CSSM_KEYBLOB_RAW_FORMAT_PKCS8,
+               512, &dsa512Params
+       },
+       {       CSSM_ALGID_DSA, 
+               CSSM_KEYBLOB_RAW_FORMAT_X509,   CSSM_KEYBLOB_RAW_FORMAT_PKCS8,
+               512, &dsa512Params
+       },
+       
+       /* Diffie-Hellman */
+       {       CSSM_ALGID_DH, 
+               CSSM_KEYBLOB_RAW_FORMAT_NONE,   CSSM_KEYBLOB_RAW_FORMAT_NONE,
+               512, &dh512Params
+       },
+       {       CSSM_ALGID_DH, 
+               CSSM_KEYBLOB_RAW_FORMAT_PKCS3,  CSSM_KEYBLOB_RAW_FORMAT_NONE,
+               512, &dh512Params
+       },
+       {       CSSM_ALGID_DH, 
+               CSSM_KEYBLOB_RAW_FORMAT_NONE,   CSSM_KEYBLOB_RAW_FORMAT_PKCS3,
+               512, &dh512Params
+       },
+       {       CSSM_ALGID_DH, 
+               CSSM_KEYBLOB_RAW_FORMAT_NONE,   CSSM_KEYBLOB_RAW_FORMAT_PKCS8,
+               512, &dh512Params
+       },
+       {       CSSM_ALGID_DH, 
+               CSSM_KEYBLOB_RAW_FORMAT_X509,   CSSM_KEYBLOB_RAW_FORMAT_NONE,
+               512, &dh512Params
+       },
+       {       CSSM_ALGID_DH, 
+               CSSM_KEYBLOB_RAW_FORMAT_X509,   CSSM_KEYBLOB_RAW_FORMAT_PKCS8,
+               512, &dh512Params
+       },
+       
+       /* FEE */
+       {       CSSM_ALGID_FEE,
+               CSSM_KEYBLOB_RAW_FORMAT_NONE,   CSSM_KEYBLOB_RAW_FORMAT_NONE,
+               127, NULL 
+       },
+       {       CSSM_ALGID_FEE,
+               CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING,   CSSM_KEYBLOB_RAW_FORMAT_NONE,
+               128, NULL 
+       },
+       {       CSSM_ALGID_FEE,
+               CSSM_KEYBLOB_RAW_FORMAT_NONE,   CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING,
+               161, NULL 
+       },
+       {       CSSM_ALGID_FEE,
+               CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING,   
+               CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING,
+               192, NULL 
+       },
+       
+};
+#define NUM_TEST_PARAMS\
+       (sizeof(KeyHashTestParams) / sizeof(KeyHashTestParams[0]))
+
+static void dumpBuf(uint8 *buf,
+       unsigned len)
+{
+       unsigned i;
+       
+       printf("   ");
+       for(i=0; i<len; i++) {
+               printf("%02X ", buf[i]);
+               if((i % 24) == 23) {
+                       printf("\n      ");
+               }
+       }
+       printf("\n");
+}
+
+const char *formStr(CSSM_KEYBLOB_FORMAT form)
+{
+       switch(form) {
+               case CSSM_KEYBLOB_RAW_FORMAT_NONE: return "NONE";
+               case CSSM_KEYBLOB_RAW_FORMAT_PKCS1: return "PKCS1";
+               case CSSM_KEYBLOB_RAW_FORMAT_PKCS3: return "PKCS3";
+               case CSSM_KEYBLOB_RAW_FORMAT_FIPS186: return "FIPS186";
+               case CSSM_KEYBLOB_RAW_FORMAT_PKCS8: return "PKCS8";
+               case CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING: return "OCTET_STRING";
+               case CSSM_KEYBLOB_RAW_FORMAT_OTHER: return "OTHER";
+               case CSSM_KEYBLOB_RAW_FORMAT_X509: return "X509";
+               case CSSM_KEYBLOB_RAW_FORMAT_OPENSSH: return "OPENSSH";
+               case CSSM_KEYBLOB_RAW_FORMAT_OPENSSL: return "OPENSSL";
+               default: 
+                       printf("**BRRZAP! formStr needs work\n");
+                       exit(1);
+       }
+}
+
+const char *algStr(CSSM_ALGORITHMS alg)
+{
+       switch(alg) {
+               case CSSM_ALGID_RSA: return "RSA";
+               case CSSM_ALGID_DSA: return "DSA";
+               case CSSM_ALGID_DH: return "DH";
+               case CSSM_ALGID_FEE: return "FEE";
+               case CSSM_ALGID_ECDSA: return "ECDSA";
+               default: 
+                       printf("**BRRZAP! algStr needs work\n");
+                       exit(1);
+       }
+}
+
+static void showTestParams(KeyHashTest *testParam)
+{
+       printf("alg %s  pubForm %s  privForm %s\n",
+                       algStr(testParam->keyAlg),
+               formStr(testParam->pubKeyForm),
+               formStr(testParam->privKeyForm));
+
+}
+
+/*
+ * 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;
+}
+
+/*
+ * Given two keys (presumably, in this test, one a raw key and 
+ * one an equivalent ref key), calculate the key digest of both of them
+ * and ensure they're the same. 
+ */
+static int compareKeyHashes(
+       const CSSM_DATA *key1Hash,
+       const char *key1Descr,
+       const CSSM_DATA *key2Hash,
+       const char *key2Descr,
+       CSSM_BOOL verbose)
+{
+       if(appCompareCssmData(key1Hash, key2Hash)) {
+               return 0;
+       }
+       printf("***Key Digest miscompare (%s,%s)***\n", key1Descr, key2Descr);
+       if(!verbose) {
+               printf("...%s hash:\n", key1Descr);
+               dumpBuf(key1Hash->Data, key1Hash->Length);
+               printf("...%s hash:\n", key2Descr);
+               dumpBuf(key2Hash->Data, key2Hash->Length);
+       }
+       return 1;
+}
+
+/*
+ * Given a KeyHashTest:
+ *     -- cook up key pair, raw, specified formats
+ *  -- NULL unwrap each raw to ref;
+ *  -- obtain four key digests;
+ *  -- ensure all digests match;
+ */
+static int doTest(
+       CSSM_CSP_HANDLE         rawCspHand,             // generate keys here
+       CSSM_CSP_HANDLE         refCspHand,             // null unwrap here
+       KeyHashTest                     *testParam,
+       CSSM_BOOL                       verbose,
+       CSSM_BOOL                       quiet)
+{
+       CSSM_RETURN crtn;
+       CSSM_KEY pubKey;
+       CSSM_KEY privKey;
+       CSSM_KEY pubKeyRef;                     
+       CSSM_KEY privKeyRef;
+       CSSM_DATA_PTR rawPubHash;
+       CSSM_DATA_PTR rawPrivHash;
+       CSSM_DATA_PTR refPubHash;
+       CSSM_DATA_PTR refPrivHash;
+       int rtn = 0;
+       
+       /* generate key pair, specified raw form */
+       crtn = genKeyPair(rawCspHand,
+               testParam->keyAlg,
+               testParam->keySizeInBits,
+               &pubKey,
+               testParam->pubKeyForm,
+               &privKey,
+               testParam->privKeyForm,
+               testParam->algParams);
+       if(crtn) {
+               return testError(quiet);
+       }
+       
+       /* null unwrap both raw keys to ref form */
+       crtn = cspRawKeyToRef(refCspHand, &pubKey, &pubKeyRef);
+       if(crtn) {
+               return testError(quiet);
+       }
+       crtn = cspRawKeyToRef(refCspHand, &privKey, &privKeyRef);
+       if(crtn) {
+               return testError(quiet);
+       }
+       
+       /* calculate four key digests */
+       crtn = cspKeyHash(rawCspHand, &pubKey, &rawPubHash);
+       if(crtn) {
+               return testError(quiet);
+       }
+       crtn = cspKeyHash(rawCspHand, &privKey, &rawPrivHash);
+       if(crtn) {
+               return testError(quiet);
+       }
+       crtn = cspKeyHash(refCspHand, &pubKeyRef, &refPubHash);
+       if(crtn) {
+               return testError(quiet);
+       }
+       crtn = cspKeyHash(refCspHand, &privKeyRef, &refPrivHash);
+       if(crtn) {
+               return testError(quiet);
+       }
+
+       if(verbose) {
+               printf("...raw pub key hash:\n");
+               dumpBuf(rawPubHash->Data, rawPubHash->Length);
+               printf("...ref pub key hash:\n");
+               dumpBuf(refPubHash->Data, refPubHash->Length);
+               printf("...raw priv key hash:\n");
+               dumpBuf(rawPrivHash->Data, rawPrivHash->Length);
+               printf("...ref priv key hash:\n");
+               dumpBuf(refPrivHash->Data, refPrivHash->Length);
+       }
+
+       /* compare */
+       rtn += compareKeyHashes(rawPubHash, "Raw public",
+               refPubHash, "Ref public", verbose);
+       rtn += compareKeyHashes(rawPrivHash, "Raw private",
+               refPrivHash, "Ref private", verbose);
+       rtn += compareKeyHashes(refPubHash, "Ref public",
+               refPrivHash, "Ref private", verbose);
+       if(rtn) {
+               rtn = testError(quiet);
+       }
+       cspFreeKey(rawCspHand, &pubKey);
+       cspFreeKey(rawCspHand, &privKey);
+       cspFreeKey(refCspHand, &pubKeyRef);
+       cspFreeKey(refCspHand, &privKeyRef);
+       appFreeCssmData(rawPubHash, CSSM_TRUE);
+       appFreeCssmData(rawPrivHash, CSSM_TRUE);
+       appFreeCssmData(refPubHash, CSSM_TRUE);
+       appFreeCssmData(refPrivHash, CSSM_TRUE);
+       return rtn;
+}
+
+int main(int argc, char **argv)
+{
+       int                                     arg;
+       char                            *argp;
+       unsigned                        loop;
+       CSSM_CSP_HANDLE         rawCspHand;             // always Raw CSP
+       CSSM_CSP_HANDLE         refCspHand;             // CSPDL if !bareCsp
+       int                                     rtn = 0;
+       int                                     i;
+       unsigned                        len;
+       
+       /*
+        * User-spec'd params
+        */
+       unsigned                        loops = LOOPS_DEF;
+       CSSM_BOOL                       verbose = CSSM_FALSE;
+       CSSM_BOOL                       quiet = CSSM_FALSE;
+       CSSM_BOOL                       bareCsp = CSSM_TRUE;
+       CSSM_BOOL                       doPause = CSSM_FALSE;
+       
+       for(arg=1; arg<argc; arg++) {
+               argp = argv[arg];
+               switch(argp[0]) {
+                   case 'l':
+                               loops = atoi(&argp[2]);
+                               break;
+                       case 'D':
+                               bareCsp = CSSM_FALSE;
+                               break;
+                   case 'p':
+                       doPause = CSSM_TRUE;
+                               break;
+                   case 'v':
+                       verbose = CSSM_TRUE;
+                               break;
+                   case 'q':
+                       quiet = CSSM_TRUE;
+                               break;
+                   case 'h':
+                   default:
+                               usage(argv);
+               }
+       }
+
+       /* prefetch the alg params */
+       rtn = readFile(DSA_PARAM_FILE, &dsa512Params.Data, &len);
+       if(rtn) {
+               printf("***%s file missing. Aborting.\n", DSA_PARAM_FILE);
+               exit(1);
+       }
+       dsa512Params.Length = len;
+       rtn = readFile(DH_PARAM_FILE, &dh512Params.Data, &len);
+       if(rtn) {
+               printf("***%s file missing. Aborting.\n", DH_PARAM_FILE);
+               exit(1);
+       }
+       dh512Params.Length = len;
+       
+       printf("Starting keyHashAsym; args: ");
+       for(i=1; i<argc; i++) {
+               printf("%s ", argv[i]);
+       }
+       printf("\n");
+       refCspHand = cspDlDbStartup(bareCsp, NULL);
+       if(refCspHand == 0) {
+               exit(1);
+       }
+       if(bareCsp) {
+               /* raw and ref on same CSP */
+               rawCspHand = refCspHand;
+       }
+       else {
+               /* generate on CSPDL, NULL unwrap to bare CSP */
+               rawCspHand = cspDlDbStartup(CSSM_TRUE, NULL);
+               if(rawCspHand == 0) {
+                       exit(1);
+               }
+       }
+       for(loop=1; ; loop++) {
+               if(!quiet) {
+                       printf("...loop %d\n", loop);
+               }
+               for(unsigned testNum=0; testNum<NUM_TEST_PARAMS; testNum++) {
+                       KeyHashTest *testParams = &KeyHashTestParams[testNum];
+                       if(!quiet) {
+                               printf("..."); showTestParams(testParams);
+                       }
+                       rtn = doTest(rawCspHand, refCspHand, testParams, verbose, quiet);
+                       if(rtn) {
+                               goto done;
+                       }
+                       if(doPause) {
+                               fpurge(stdin);
+                               printf("Hit CR to proceed: ");
+                               getchar();
+                       }
+               }
+               if(loops && (loop == loops)) {
+                       break;
+               }
+       }
+done:
+       if((rtn == 0) && !quiet) {
+               printf("...%s complete\n", argv[0]);
+       }
+       return rtn;
+}