1 /* Copyright (c) 2004-2005,2008 Apple Inc. 
   3  * dbVerifyKey.cpp - verify that specified DB has exactly one key of specified 
   4  * algorithm, class, and key size - and no other keys. 
  11 #include <Security/cssm.h> 
  12 #include <Security/cssmapple.h> 
  15 #include "cspdlTesting.h" 
  18 static void usage(char **argv
) 
  20         printf("usage: %s dbFileName alg class keysize [options]\n", argv
[0]); 
  21         printf("   alg   : rsa|dsa|dh|ecdsa\n"); 
  22         printf("   class : priv|pub\n"); 
  24         printf("   -q   quiet\n"); 
  28 static const char *recordTypeStr( 
  29         CSSM_DB_RECORDTYPE              recordType
) 
  34                 case CSSM_DL_DB_RECORD_PRIVATE_KEY
: 
  36                 case CSSM_DL_DB_RECORD_PUBLIC_KEY
: 
  38                 case CSSM_DL_DB_RECORD_SYMMETRIC_KEY
: 
  39                         return "Symmetric Key"; 
  41                         sprintf(unk
, "**Unknown record type %u\n", (unsigned)recordType
); 
  47  * Search for specified record type; verify there is exactly one or zero 
  48  * of them as specified. 
  49  * Verify key algorthm and key size. Returns nonzero on error.  
  52         CSSM_DL_DB_HANDLE               dlDbHand
, 
  53         unsigned                                numRecords
,             // zero or one 
  54         CSSM_DB_RECORDTYPE              recordType
, 
  56         CSSM_ALGORITHMS                 keyAlg
) 
  59         CSSM_DB_UNIQUE_RECORD_PTR               record 
= NULL
; 
  61         CSSM_HANDLE                                             resultHand
; 
  62         CSSM_DB_RECORD_ATTRIBUTE_DATA   recordAttrs
; 
  64         /* no predicates, all records of specified type, no attrs, get the key */ 
  65         query
.RecordType 
= recordType
; 
  66         query
.Conjunctive 
= CSSM_DB_NONE
; 
  67         query
.NumSelectionPredicates 
= 0;        
  68         query
.QueryLimits
.TimeLimit 
= 0;        // FIXME - meaningful? 
  69         query
.QueryLimits
.SizeLimit 
= 1;        // FIXME - meaningful? 
  70         query
.QueryFlags 
= 0; // CSSM_QUERY_RETURN_DATA;        // FIXME - used? 
  72         recordAttrs
.DataRecordType               
= recordType
; 
  73         recordAttrs
.NumberOfAttributes   
= 0; 
  74         recordAttrs
.AttributeData        
= NULL
; 
  76         CSSM_DATA recordData 
= {0, NULL
}; 
  78         crtn 
= CSSM_DL_DataGetFirst(dlDbHand
, 
  87                                 printf("***Expected zero records of type %s, found one\n", 
  88                                         recordTypeStr(recordType
)); 
  89                                 CSSM_DL_FreeUniqueRecord(dlDbHand
, record
); 
  90                                 CSSM_DL_DataAbortQuery(dlDbHand
, resultHand
); 
  94                 case CSSMERR_DL_ENDOFDATA
: 
  99                         printf("**Error: no records of type %s found\n", 
 100                                 recordTypeStr(recordType
)); 
 103                         printError("DataGetFirst", crtn
); 
 107         CSSM_KEY_PTR theKey 
= (CSSM_KEY_PTR
)recordData
.Data
; 
 109         CSSM_KEYHEADER 
&hdr 
= theKey
->KeyHeader
; 
 110         if(hdr
.AlgorithmId 
!= keyAlg
) { 
 111                 printf("***Algorithm mismatch: expect %u, got %u\n", 
 112                         (unsigned)keyAlg
, (unsigned)hdr
.AlgorithmId
); 
 115         if(hdr
.LogicalKeySizeInBits 
!= keySize
) { 
 116                 printf("***Key Size: expect %u, got %u\n", 
 117                         (unsigned)keySize
, (unsigned)hdr
.LogicalKeySizeInBits
); 
 120         CSSM_DL_FreeUniqueRecord(dlDbHand
, record
); 
 122         /* see if there are any more */ 
 123         crtn 
= CSSM_DL_DataGetNext(dlDbHand
, 
 128         if(crtn 
== CSSM_OK
) { 
 129                 printf("***More than 1 record of type %s found\n",  
 130                         recordTypeStr(recordType
)); 
 132                 CSSM_DL_FreeUniqueRecord(dlDbHand
, record
); 
 134         CSSM_DL_DataAbortQuery(dlDbHand
, resultHand
); 
 145         CSSM_ALGORITHMS         keyAlg
; 
 146         CSSM_DB_RECORDTYPE      recordType
; 
 148         CSSM_DL_DB_HANDLE       dlDbHand
; 
 149         CSSM_BOOL                       quiet 
= CSSM_FALSE
; 
 150         CSSM_RETURN             crtn 
= CSSM_OK
; 
 155         dbFileName 
= argv
[1]; 
 158         if(!strcmp(argv
[2], "rsa")) { 
 159                 keyAlg 
= CSSM_ALGID_RSA
; 
 161         else if(!strcmp(argv
[2], "dsa")) { 
 162                 keyAlg 
= CSSM_ALGID_DSA
; 
 164         else if(!strcmp(argv
[2], "dh")) { 
 165                 keyAlg 
= CSSM_ALGID_DH
; 
 167         else if(!strcmp(argv
[2], "ecdsa")) { 
 168                 keyAlg 
= CSSM_ALGID_ECDSA
; 
 175         if(!strcmp(argv
[3], "priv")) { 
 176                 recordType 
= CSSM_DL_DB_RECORD_PRIVATE_KEY
; 
 178         else if(!strcmp(argv
[3], "pub")) { 
 179                 recordType 
= CSSM_DL_DB_RECORD_PUBLIC_KEY
; 
 185         keySize 
= atoi(argv
[4]); 
 187         for(arg
=5; arg
<argc
; arg
++) { 
 189                 if(!strcmp(argp
, "-q")) { 
 197         dlDbHand
.DLHandle 
= dlStartup(); 
 198         if(dlDbHand
.DLHandle 
== 0) { 
 201         crtn 
= dbCreateOpen(dlDbHand
.DLHandle
, dbFileName
,  
 202                 CSSM_FALSE
, CSSM_FALSE
, NULL
, &dlDbHand
.DBHandle
); 
 207         if(doVerify(dlDbHand
, 1, recordType
, keySize
, keyAlg
)) { 
 210         if(doVerify(dlDbHand
, 0,  
 211                         (recordType 
== CSSM_DL_DB_RECORD_PRIVATE_KEY
) ? 
 212                                 CSSM_DL_DB_RECORD_PUBLIC_KEY 
: CSSM_DL_DB_RECORD_PRIVATE_KEY
, 
 217                 printf("...%s verify succussful\n", recordTypeStr(recordType
)); 
 219         CSSM_DL_DbClose(dlDbHand
); 
 220         CSSM_ModuleDetach(dlDbHand
.DLHandle
);