1/* 2 * keyHash.c - simple test of CSSM_APPLECSP_KEYDIGEST passthrough 3 */ 4 5#include <stdlib.h> 6#include <stdio.h> 7#include <time.h> 8#include <string.h> 9#include <Security/cssm.h> 10#include "cspwrap.h" 11#include "common.h" 12#include "cspdlTesting.h" 13 14#define USAGE_NAME "noUsage" 15#define USAGE_NAME_LEN (strlen(USAGE_NAME)) 16#define LOOPS_DEF 10 17 18static void usage(char **argv) 19{ 20 printf("usage: %s [options]\n", argv[0]); 21 printf("Options:\n"); 22 printf(" l=loops (default=%d; 0=forever)\n", LOOPS_DEF); 23 printf(" D (CSP/DL; default = bare CSP)\n"); 24 printf(" p(ause on each loop)\n"); 25 printf(" q(uiet)\n"); 26 printf(" v(erbose))\n"); 27 exit(1); 28} 29 30static void dumpBuf(uint8 *buf, 31 unsigned len) 32{ 33 unsigned i; 34 35 printf(" "); 36 for(i=0; i<len; i++) { 37 printf("%02X ", buf[i]); 38 if((i % 24) == 23) { 39 printf("\n "); 40 } 41 } 42 printf("\n"); 43} 44 45/* 46 * Given a ref key: 47 * NULL wrap to data key; 48 * obtain hash of both keys; 49 * ensure hashes are equal; 50 */ 51static int doTest( 52 CSSM_CSP_HANDLE cspHand, // raw or CSPDL 53 CSSM_CSP_HANDLE rawCspHand, // raw, may be same as cspHand 54 CSSM_KEY_PTR refKey, 55 CSSM_BOOL verbose, 56 CSSM_BOOL quiet) 57{ 58 CSSM_KEY rawKey; 59 CSSM_RETURN crtn; 60 CSSM_DATA_PTR refHash; 61 CSSM_DATA_PTR rawHash; 62 63 if(refKey->KeyHeader.BlobType != CSSM_KEYBLOB_REFERENCE) { 64 printf("Hey! this only works on ref keys!!\n"); 65 exit(1); 66 } 67 68 /* get raw key */ 69 crtn = cspWrapKey(cspHand, 70 refKey, 71 NULL, // wrappingKey 72 CSSM_ALGID_NONE, 73 CSSM_ALGMODE_NONE, 74 CSSM_KEYBLOB_WRAPPED_FORMAT_NONE, 75 CSSM_PADDING_NONE, 76 NULL, // iv 77 NULL, // descData 78 &rawKey); 79 if(crtn) { 80 return testError(quiet); 81 } 82 83 /* hash of both keys */ 84 crtn = cspKeyHash(cspHand, refKey, &refHash); 85 if(crtn) { 86 return testError(quiet); 87 } 88 else { 89 if(verbose) { 90 printf(" ...Ref key hash:\n "); 91 dumpBuf(refHash->Data, refHash->Length); 92 } 93 } 94 crtn = cspKeyHash(rawCspHand, &rawKey, &rawHash); 95 if(crtn) { 96 return testError(quiet); 97 } 98 else { 99 if(verbose) { 100 printf(" ...Raw key hash:\n "); 101 dumpBuf(rawHash->Data, rawHash->Length); 102 } 103 } 104 if(!appCompareCssmData(refHash, rawHash)) { 105 printf("***Key Hash Miscompare!\n"); 106 return testError(quiet); 107 } 108 appFreeCssmData(refHash, CSSM_TRUE); 109 appFreeCssmData(rawHash, CSSM_TRUE); 110 cspFreeKey(cspHand, &rawKey); 111 return 0; 112} 113 114int main(int argc, char **argv) 115{ 116 int arg; 117 char *argp; 118 unsigned loop; 119 CSSM_CSP_HANDLE cspHand; 120 CSSM_CSP_HANDLE rawCspHand; 121 int rtn = 0; 122 CSSM_KEY pubKey; 123 CSSM_KEY privKey; 124 CSSM_KEY_PTR symKey; 125 int i; 126 127 /* 128 * User-spec'd params 129 */ 130 unsigned loops = LOOPS_DEF; 131 CSSM_BOOL verbose = CSSM_FALSE; 132 CSSM_BOOL quiet = CSSM_FALSE; 133 CSSM_BOOL bareCsp = CSSM_TRUE; 134 CSSM_BOOL doPause = CSSM_FALSE; 135 136 for(arg=1; arg<argc; arg++) { 137 argp = argv[arg]; 138 switch(argp[0]) { 139 case 'l': 140 loops = atoi(&argp[2]); 141 break; 142 case 'D': 143 bareCsp = CSSM_FALSE; 144 break; 145 case 'p': 146 doPause = CSSM_TRUE; 147 break; 148 case 'v': 149 verbose = CSSM_TRUE; 150 break; 151 case 'q': 152 quiet = CSSM_TRUE; 153 break; 154 case 'h': 155 default: 156 usage(argv); 157 } 158 } 159 160 printf("Starting keyHash; args: "); 161 for(i=1; i<argc; i++) { 162 printf("%s ", argv[i]); 163 } 164 printf("\n"); 165 cspHand = cspDlDbStartup(bareCsp, NULL); 166 if(cspHand == 0) { 167 exit(1); 168 } 169 if(bareCsp) { 170 rawCspHand = cspHand; 171 } 172 else { 173 rawCspHand = cspDlDbStartup(CSSM_TRUE, NULL); 174 if(rawCspHand == 0) { 175 exit(1); 176 } 177 } 178 for(loop=1; ; loop++) { 179 if(!quiet) { 180 printf("...loop %d\n", loop); 181 } 182 183 /* first with symmetric key */ 184 if(verbose) { 185 printf(" ...testing DES key\n"); 186 } 187 symKey = cspGenSymKey(cspHand, 188 CSSM_ALGID_DES, 189 USAGE_NAME, 190 USAGE_NAME_LEN, 191 CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_DECRYPT, 192 64, 193 CSSM_TRUE); // refKey 194 if(symKey == NULL) { 195 if(testError(quiet)) { 196 break; 197 } 198 } 199 if(doTest(cspHand, rawCspHand, symKey, verbose, quiet)) { 200 break; 201 } 202 CSSM_FreeKey(cspHand, NULL, symKey, CSSM_TRUE); 203 CSSM_FREE(symKey); 204 205 /* cook up an RSA key pair */ 206 rtn = cspGenKeyPair(cspHand, 207 CSSM_ALGID_RSA, 208 USAGE_NAME, 209 USAGE_NAME_LEN, 210 CSP_RSA_KEY_SIZE_DEFAULT, 211 &pubKey, 212 CSSM_TRUE, // pubIsRef 213 CSSM_KEYUSE_ENCRYPT, 214 CSSM_KEYBLOB_RAW_FORMAT_NONE, 215 &privKey, 216 CSSM_TRUE, // privIsRef 217 CSSM_KEYUSE_DECRYPT, 218 CSSM_KEYBLOB_RAW_FORMAT_NONE, 219 CSSM_FALSE); // genSeed 220 if(rtn) { 221 if(testError(quiet)) { 222 break; 223 } 224 } 225 if(verbose) { 226 printf(" ...testing RSA public key\n"); 227 } 228 if(doTest(cspHand, rawCspHand, &pubKey, verbose, quiet)) { 229 break; 230 } 231 if(verbose) { 232 printf(" ...testing RSA private key\n"); 233 } 234 if(doTest(cspHand, rawCspHand, &privKey, verbose, quiet)) { 235 break; 236 } 237 CSSM_FreeKey(cspHand, NULL, &pubKey, CSSM_TRUE); 238 CSSM_FreeKey(cspHand, NULL, &privKey, CSSM_TRUE); 239 if(loops && (loop == loops)) { 240 break; 241 } 242 if(doPause) { 243 fpurge(stdin); 244 printf("Hit CR to proceed: "); 245 getchar(); 246 } 247 } 248 return 0; 249} 250