]> git.saurik.com Git - apple/security.git/blobdiff - SecurityTests/cspxutils/dbVerifyKey/dbVerifyKey.cpp
Security-57031.1.35.tar.gz
[apple/security.git] / SecurityTests / cspxutils / dbVerifyKey / dbVerifyKey.cpp
diff --git a/SecurityTests/cspxutils/dbVerifyKey/dbVerifyKey.cpp b/SecurityTests/cspxutils/dbVerifyKey/dbVerifyKey.cpp
new file mode 100644 (file)
index 0000000..d190e92
--- /dev/null
@@ -0,0 +1,222 @@
+/* Copyright (c) 2004-2005,2008 Apple Inc.
+ *
+ * dbVerifyKey.cpp - verify that specified DB has exactly one key of specified
+ * algorithm, class, and key size - and no other keys.
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <strings.h>
+#include <ctype.h>
+#include <Security/cssm.h>
+#include <Security/cssmapple.h>
+#include "cspwrap.h"
+#include "common.h"
+#include "cspdlTesting.h"
+
+
+static void usage(char **argv)
+{
+       printf("usage: %s dbFileName alg class keysize [options]\n", argv[0]);
+       printf("   alg   : rsa|dsa|dh|ecdsa\n");
+       printf("   class : priv|pub\n");
+       printf("Options:\n");
+       printf("   -q   quiet\n");
+       exit(1);
+}
+
+static const char *recordTypeStr(
+       CSSM_DB_RECORDTYPE              recordType)
+{
+       static char unk[100];
+       
+       switch(recordType) {
+               case CSSM_DL_DB_RECORD_PRIVATE_KEY:
+                       return "Private Key";
+               case CSSM_DL_DB_RECORD_PUBLIC_KEY:
+                       return "Public Key";
+               case CSSM_DL_DB_RECORD_SYMMETRIC_KEY:
+                       return "Symmetric Key";
+               default:
+                       sprintf(unk, "**Unknown record type %u\n", (unsigned)recordType);
+                       return unk;
+       }
+}
+
+/*
+ * Search for specified record type; verify there is exactly one or zero
+ * of them as specified.
+ * Verify key algorthm and key size. Returns nonzero on error. 
+ */
+static int doVerify(
+       CSSM_DL_DB_HANDLE               dlDbHand,
+       unsigned                                numRecords,             // zero or one
+       CSSM_DB_RECORDTYPE              recordType,
+       uint32                                  keySize,
+       CSSM_ALGORITHMS                 keyAlg)
+{
+       CSSM_QUERY                                              query;
+       CSSM_DB_UNIQUE_RECORD_PTR               record = NULL;
+       CSSM_RETURN                                             crtn;
+       CSSM_HANDLE                                             resultHand;
+       CSSM_DB_RECORD_ATTRIBUTE_DATA   recordAttrs;
+       
+       /* no predicates, all records of specified type, no attrs, get the key */
+       query.RecordType = recordType;
+       query.Conjunctive = CSSM_DB_NONE;
+       query.NumSelectionPredicates = 0;       
+       query.QueryLimits.TimeLimit = 0;        // FIXME - meaningful?
+       query.QueryLimits.SizeLimit = 1;        // FIXME - meaningful?
+       query.QueryFlags = 0; // CSSM_QUERY_RETURN_DATA;        // FIXME - used?
+       
+       recordAttrs.DataRecordType               = recordType;
+       recordAttrs.NumberOfAttributes   = 0;
+       recordAttrs.AttributeData        = NULL;
+
+       CSSM_DATA recordData = {0, NULL};
+
+       crtn = CSSM_DL_DataGetFirst(dlDbHand,
+               &query,
+               &resultHand,
+               &recordAttrs,
+               &recordData,    
+               &record);
+       switch(crtn) {
+               case CSSM_OK:
+                       if(numRecords == 0) {
+                               printf("***Expected zero records of type %s, found one\n",
+                                       recordTypeStr(recordType));
+                               CSSM_DL_FreeUniqueRecord(dlDbHand, record);
+                               CSSM_DL_DataAbortQuery(dlDbHand, resultHand);
+                               return 1;
+                       }
+                       break;          // proceed
+               case CSSMERR_DL_ENDOFDATA:
+                       if(numRecords == 0) {
+                               /* cool */
+                               return 0;
+                       }
+                       printf("**Error: no records of type %s found\n",
+                               recordTypeStr(recordType));
+                       return 1;
+               default:
+                       printError("DataGetFirst", crtn);
+                       return 1;
+       }
+
+       CSSM_KEY_PTR theKey = (CSSM_KEY_PTR)recordData.Data;
+       int ourRtn = 0;
+       CSSM_KEYHEADER &hdr = theKey->KeyHeader;
+       if(hdr.AlgorithmId != keyAlg) {
+               printf("***Algorithm mismatch: expect %u, got %u\n",
+                       (unsigned)keyAlg, (unsigned)hdr.AlgorithmId);
+               ourRtn++;
+       }
+       if(hdr.LogicalKeySizeInBits != keySize) {
+               printf("***Key Size: expect %u, got %u\n",
+                       (unsigned)keySize, (unsigned)hdr.LogicalKeySizeInBits);
+               ourRtn++;
+       }
+       CSSM_DL_FreeUniqueRecord(dlDbHand, record);
+
+       /* see if there are any more */
+       crtn = CSSM_DL_DataGetNext(dlDbHand,
+               resultHand, 
+               &recordAttrs,
+               NULL,
+               &record);
+       if(crtn == CSSM_OK) {
+               printf("***More than 1 record of type %s found\n", 
+                       recordTypeStr(recordType));
+               ourRtn++;
+               CSSM_DL_FreeUniqueRecord(dlDbHand, record);
+       }
+       CSSM_DL_DataAbortQuery(dlDbHand, resultHand);
+       return ourRtn;
+}
+
+int main(
+       int argc, 
+       char **argv)
+{
+       int                                     arg;
+       char                            *argp;
+       char                            *dbFileName;
+       CSSM_ALGORITHMS         keyAlg;
+       CSSM_DB_RECORDTYPE      recordType;
+       uint32                          keySize;
+       CSSM_DL_DB_HANDLE       dlDbHand;
+       CSSM_BOOL                       quiet = CSSM_FALSE;
+       CSSM_RETURN             crtn = CSSM_OK;
+       
+       if(argc < 5) {
+               usage(argv);
+       }
+       dbFileName = argv[1];
+       
+       /* key algorithm */
+       if(!strcmp(argv[2], "rsa")) {
+               keyAlg = CSSM_ALGID_RSA;
+       }
+       else if(!strcmp(argv[2], "dsa")) {
+               keyAlg = CSSM_ALGID_DSA;
+       }
+       else if(!strcmp(argv[2], "dh")) {
+               keyAlg = CSSM_ALGID_DH;
+       }
+       else if(!strcmp(argv[2], "ecdsa")) {
+               keyAlg = CSSM_ALGID_ECDSA;
+       }
+       else {
+               usage(argv);
+       }
+       
+       /* key class */
+       if(!strcmp(argv[3], "priv")) {
+               recordType = CSSM_DL_DB_RECORD_PRIVATE_KEY;
+       }
+       else if(!strcmp(argv[3], "pub")) {
+               recordType = CSSM_DL_DB_RECORD_PUBLIC_KEY;
+       }
+       else {
+               usage(argv);
+       }
+
+       keySize = atoi(argv[4]);
+       
+       for(arg=5; arg<argc; arg++) {
+               argp = argv[arg];
+               if(!strcmp(argp, "-q")) {
+                       quiet = CSSM_TRUE;
+               }
+               else {
+                       usage(argv);
+               }
+       }
+       
+       dlDbHand.DLHandle = dlStartup();
+       if(dlDbHand.DLHandle == 0) {
+               exit(1);
+       }
+       crtn = dbCreateOpen(dlDbHand.DLHandle, dbFileName, 
+               CSSM_FALSE, CSSM_FALSE, NULL, &dlDbHand.DBHandle);
+       if(crtn) {
+               exit(1);
+       }
+       
+       if(doVerify(dlDbHand, 1, recordType, keySize, keyAlg)) {
+               return 1;
+       }
+       if(doVerify(dlDbHand, 0, 
+                       (recordType == CSSM_DL_DB_RECORD_PRIVATE_KEY) ?
+                               CSSM_DL_DB_RECORD_PUBLIC_KEY : CSSM_DL_DB_RECORD_PRIVATE_KEY,
+                       keySize, keyAlg)) {
+               return 1;
+       }
+       if(!quiet) {
+               printf("...%s verify succussful\n", recordTypeStr(recordType));
+       }
+       CSSM_DL_DbClose(dlDbHand);
+       CSSM_ModuleDetach(dlDbHand.DLHandle);
+       return 0;
+}