/* * This only gets called when cspAttacher get deleted, i.e., when this code * is actually unloaded from the process's address space. */ CSPAttacher::~CSPAttacher() { StLock<Mutex> _(mLock); if(mCspHand != CSSM_INVALID_HANDLE) { CSSM_ModuleDetach(mCspHand); CSSM_ModuleUnload(&gGuidAppleCSP, NULL, NULL); } if(mCspDlHand != CSSM_INVALID_HANDLE) { CSSM_ModuleDetach(mCspDlHand); CSSM_ModuleUnload(&gGuidAppleCSPDL, NULL, NULL); } }
/* * Detach and unload from a CSP. */ CSSM_RETURN cspShutdown( CSSM_CSP_HANDLE cspHand, CSSM_BOOL bareCsp) // true ==> CSP, false ==> CSP/DL { CSSM_RETURN crtn; const CSSM_GUID *guid; char *modName; if(bareCsp) { guid = &gGuidAppleCSP; modName = (char *) "AppleCSP"; } else { guid = &gGuidAppleCSPDL; modName = (char *) "AppleCSPDL"; } crtn = CSSM_ModuleDetach(cspHand); if(crtn) { printf("Error detaching from %s\n", modName); printError("CSSM_ModuleDetach", crtn); return crtn; } crtn = CSSM_ModuleUnload(guid, NULL, NULL); if(crtn) { printf("Error unloading %s\n", modName); printError("CSSM_ModuleUnload", crtn); } return crtn; }
void cdsaShutdown(void) { CSSM_ModuleDetach(cspHandle); CSSM_ModuleUnload(&gGuidAppleCSP, /*AppNotifyCallback*/ NULL, /*AppNotifyCallbackCtx*/ NULL); CSSM_Terminate(); }
DotMacRelation::~DotMacRelation () { if (mCertificateLibrary != 0) { CSSM_ModuleDetach (mCertificateLibrary); } }
CSSM_RETURN pkiClDetachUnload( CSSM_CL_HANDLE clHand) { CSSM_RETURN crtn = CSSM_ModuleDetach(clHand); if(crtn) { return crtn; } return CSSM_ModuleUnload(&gGuidAppleX509CL, NULL, NULL); }
CSSM_RETURN cuDlDetachUnload( CSSM_DL_HANDLE dlHand) { CSSM_RETURN crtn = CSSM_ModuleDetach(dlHand); if(crtn) { return crtn; } return CSSM_ModuleUnload(&gGuidAppleCSPDL, NULL, NULL); }
CSSM_RETURN cuTpDetachUnload( CSSM_TP_HANDLE tpHand) { CSSM_RETURN crtn = CSSM_ModuleDetach(tpHand); if(crtn) { return crtn; } return CSSM_ModuleUnload(&gGuidAppleX509TP, NULL, NULL); }
void CryptoMac_FreePublicKey(CryptoX_PublicKey* aPublicKey) { if (!aPublicKey || !*aPublicKey) { return; } if (!OnLionOrLater() && sCspHandle) { CSSM_ModuleDetach(sCspHandle); sCspHandle = NULL; } CFRelease((SecKeyRef)*aPublicKey); }
/* detach and unload */ CSSM_RETURN cuCspDetachUnload( CSSM_CSP_HANDLE cspHand, CSSM_BOOL bareCsp) // true ==> CSP, false ==> CSP/DL { CSSM_RETURN crtn = CSSM_ModuleDetach(cspHand); if(crtn) { return crtn; } const CSSM_GUID *guid; if(bareCsp) { guid = &gGuidAppleCSP; } else { guid = &gGuidAppleCSPDL; } return CSSM_ModuleUnload(guid, NULL, NULL); }
void clShutdown( CSSM_CL_HANDLE clHand) { CSSM_RETURN crtn; crtn = CSSM_ModuleDetach(clHand); if(crtn) { printf("Error detaching from AppleCL\n"); printError("CSSM_ModuleDetach", crtn); return; } crtn = CSSM_ModuleUnload(&gGuidAppleX509CL, NULL, NULL); if(crtn) { printf("Error unloading AppleCL\n"); printError("CSSM_ModuleUnload", crtn); } }
void tpShutdown( CSSM_TP_HANDLE tpHand) { CSSM_RETURN crtn; crtn = CSSM_ModuleDetach(tpHand); if(crtn) { printf("Error detaching from AppleTP\n"); printError("CSSM_ModuleDetach", crtn); return; } crtn = CSSM_ModuleUnload(&gGuidAppleX509TP, NULL, NULL); if(crtn) { printf("Error unloading AppleTP\n"); printError("CSSM_ModuleUnload", crtn); } }
int main(int argc, char **argv) { int arg; char *argp; CSSM_HANDLE modHand = 0; void *foo; CSSM_SERVICE_TYPE svcType = CSSM_SERVICE_CSP; const CSSM_GUID *guid = &gGuidAppleCSP; const char *modName = "AppleCSP"; CSSM_RETURN crtn; CSSM_BOOL doLoad = CSSM_FALSE; CSSM_BOOL doUnload = CSSM_FALSE; /* force link against malloc */ foo = malloc(1); for(arg=1; arg<argc; arg++) { argp = argv[arg]; switch(argp[0]) { case 'l': doLoad = CSSM_TRUE; break; case 'u': doLoad = doUnload = CSSM_TRUE; break; case 'd': guid = &gGuidAppleCSPDL; modName = "AppleCSPDL"; break; case 'c': guid = &gGuidAppleX509CL; svcType = CSSM_SERVICE_CL; modName = "AppleX509CL"; break; case 't': guid = &gGuidAppleX509TP; svcType = CSSM_SERVICE_TP; modName = "AppleX509TP"; break; case 'h': default: usage(argv); } } if(doPause("Top of test")) { goto done; } /* CSSM init, just once */ if(!cssmStartup()) { printf("Oops, error starting up CSSM\n"); exit(1); } if(doPause("CSSM initialized")) { goto done; } if(!doLoad) { /* load, just once */ crtn = CSSM_ModuleLoad(guid, CSSM_KEY_HIERARCHY_NONE, NULL, // eventHandler NULL); // AppNotifyCallbackCtx if(crtn) { printf("Error loading %s\n", modName); printError("CSSM_ModuleLoad", crtn); return 0; } if(doPause("CSSM_ModuleLoad() complete")) { goto done; } } while(1) { if(doLoad) { /* load, each time */ crtn = CSSM_ModuleLoad(guid, CSSM_KEY_HIERARCHY_NONE, NULL, // eventHandler NULL); // AppNotifyCallbackCtx if(crtn) { printf("Error loading %s\n", modName); printError("CSSM_ModuleLoad", crtn); return 0; } if(doPause("CSSM_ModuleLoad() complete")) { break; } } crtn = CSSM_ModuleAttach (guid, &vers, &memFuncs, // memFuncs 0, // SubserviceID svcType, 0, // AttachFlags CSSM_KEY_HIERARCHY_NONE, NULL, // FunctionTable 0, // NumFuncTable NULL, // reserved &modHand); if(crtn) { printf("Error attaching to %s\n", modName); printError("CSSM_ModuleAttach", crtn); return 0; } if(doPause("ModuleAttach() complete")) { break; } CSSM_ModuleDetach(modHand); modHand = 0; if(doPause("ModuleDetach() complete")) { break; } if(doUnload) { /* unload, each time */ crtn = CSSM_ModuleUnload(guid, NULL, NULL); if(crtn) { printf("Error unloading %s\n", modName); printError("CSSM_ModuleUnload", crtn); return 0; } if(doPause("ModuleUnload() complete")) { break; } } /* unloading */ } /* main loop */ done: fpurge(stdin); if(modHand) { CSSM_ModuleDetach(modHand); printf("Final detach complete; cr to exit: "); } else { printf("Test complete; cr to exit: "); } getchar(); return 0; }
int main(int argc, char **argv) { CSSM_CL_HANDLE clHand; // CL handle CSSM_DATA rawCert = {0, NULL}; uint32 numFields; CSSM_HANDLE ResultsHandle = 0; char baseName[255]; char blobName[255]; char *cp; int rtn; int nameLen; CSSM_RETURN crtn; CSSM_DATA_PTR value; CSSM_KEY_PTR key; uint32 keySize; NSS_Certificate signedCert; SecAsn1CoderRef coder; if(argc != 2) { printf("usage: %s certFile\n", argv[0]); exit(1); } /* connect to CL */ clHand = clStartup(); if(clHand == 0) { printf("clStartup failure; aborting\n"); return 0; } /* subsequent errors to abort: */ /* read a in raw cert */ unsigned len; rtn = readFile(argv[1], &rawCert.Data, &len); if(rtn) { printf("Error %s reading file %s\n", strerror(rtn), argv[1]); exit(1); } rawCert.Length = len; /* C string of file name, terminating at '.' or space */ nameLen = strlen(argv[1]); memmove(baseName, argv[1], nameLen); baseName[nameLen] = '\0'; cp = strchr(baseName, '.'); if(cp) { *cp = '\0'; } cp = strchr(baseName, ' '); if(cp) { *cp = '\0'; } /* print filename and parsed subject name as comment */ crtn = CSSM_CL_CertGetFirstFieldValue( clHand, &rawCert, &CSSMOID_X509V1SubjectNameCStruct, &ResultsHandle, &numFields, &value); if(crtn) { printError("CSSM_CL_CertGetFirstFieldValue(CSSMOID_X509V1SubjectNameCStruct)", crtn); goto abort; } CSSM_CL_CertAbortQuery(clHand, ResultsHandle); if(value == NULL) { printf("Error extracting subject name\n"); goto abort; } printHeader(argv[1], value); CSSM_CL_FreeFieldValue(clHand, &CSSMOID_X509V1SubjectNameCStruct, value); /* print normalized & encoded subject name as C data */ crtn = CSSM_CL_CertGetFirstFieldValue( clHand, &rawCert, &SUBJECT_NAME_OID, &ResultsHandle, &numFields, &value); if(crtn) { printError("CSSM_CL_CertGetFirstFieldValue(CSSMOID_X509V1SubjectName)", crtn); goto abort; } CSSM_CL_CertAbortQuery(clHand, ResultsHandle); if(value == NULL) { printf("Error extracting subject name\n"); goto abort; } sprintf(blobName, "%s_subject", baseName); dumpDataBlob(blobName, value); #if WRITE_NAME_FILE writeFile(blobName, value->Data, (unsigned)value->Length); #endif CSSM_CL_FreeFieldValue(clHand, &SUBJECT_NAME_OID, value); /* print key blob as data */ crtn = CSSM_CL_CertGetFirstFieldValue( clHand, &rawCert, &CSSMOID_CSSMKeyStruct, &ResultsHandle, &numFields, &value); if(crtn) { printError("CSSM_CL_CertGetFirstFieldValue(CSSMOID_CSSMKeyStruct)", crtn); goto abort; } CSSM_CL_CertAbortQuery(clHand, ResultsHandle ); if(value == NULL) { printf("Error extracting public key\n"); goto abort; } if(value->Length != sizeof(CSSM_KEY)) { printf("CSSMOID_CSSMKeyStruct length error\n"); goto abort; } key = (CSSM_KEY_PTR)value->Data; sprintf(blobName, "%s_pubKey", baseName); dumpDataBlob(blobName, &key->KeyData); keySize = key->KeyHeader.LogicalKeySizeInBits; CSSM_CL_FreeFieldValue(clHand, &CSSMOID_CSSMKeyStruct, value); /* unnormalized DER-encoded issuer */ SecAsn1CoderCreate(&coder); memset(&signedCert, 0, sizeof(signedCert)); if(SecAsn1DecodeData(coder, &rawCert, kSecAsn1SignedCertTemplate, &signedCert)) { printf("***Error NSS-decoding certificate\n"); } else { sprintf(blobName, "%s_derIssuer", baseName); dumpDataBlob(blobName, &signedCert.tbs.derIssuer); } /* now the the struct containing all three */ printf("\n { &%s_subject, &%s_pubKey, %u },\n", baseName, baseName, (unsigned)keySize); abort: free(rawCert.Data); if(clHand != 0) { CSSM_ModuleDetach(clHand); } SecAsn1CoderRelease(coder); return 0; }
/* * Detach from CSP. To be called when app is finished with this * library. */ CSSM_RETURN cdsaCspDetach( CSSM_CSP_HANDLE cspHandle) { return CSSM_ModuleDetach(cspHandle); }
int main(int argc, char **argv) { CSSM_CL_HANDLE clHand; // CL handle CSSM_X509_NAME *subjName; CSSM_X509_NAME *rootName; CSSM_X509_TIME *notBefore; // UTC-style "not before" time CSSM_X509_TIME *notAfter; // UTC-style "not after" time CSSM_DATA_PTR rawCert; // from CSSM_CL_CertCreateTemplate CSSM_DATA signedRootCert; // from CSSM_CL_CertSign CSSM_DATA signedSubjCert; // from CSSM_CL_CertSign CSSM_CSP_HANDLE cspHand; // CSP handle CSSM_KEY subjPubKey; // subject's RSA public key blob CSSM_KEY subjPrivKey; // subject's RSA private key - ref format CSSM_KEY rootPubKey; // root's RSA public key blob CSSM_KEY rootPrivKey; // root's RSA private key - ref format CSSM_RETURN crtn; CSSM_KEY_PTR extractRootKey; // from CSSM_CL_CertGetKeyInfo() CSSM_KEY_PTR extractSubjKey; // ditto CSSM_CC_HANDLE signContext; // for signing/verifying the cert unsigned badByte; int arg; unsigned errorCount = 0; /* user-spec'd variables */ CSSM_BOOL writeBlobs = CSSM_FALSE; CSSM_ALGORITHMS keyAlg = KEY_ALG_DEFAULT; CSSM_ALGORITHMS sigAlg = SIG_ALG_DEFAULT; uint32 keySizeInBits = CSP_KEY_SIZE_DEFAULT; /* * Two extensions. Subject has one (KeyUsage); root has KeyUsage and * BasicConstraints. */ CSSM_X509_EXTENSION exts[2]; CE_KeyUsage keyUsage; CE_BasicConstraints bc; for(arg=1; arg<argc; arg++) { switch(argv[arg][0]) { case 'w': writeBlobs = CSSM_TRUE; break; case 'a': if((argv[arg][1] == '\0') || (argv[arg][2] == '\0')) { usage(argv); } switch(argv[arg][2]) { case 's': keyAlg = CSSM_ALGID_RSA; sigAlg = CSSM_ALGID_SHA1WithRSA; break; case 'm': keyAlg = CSSM_ALGID_RSA; sigAlg = CSSM_ALGID_MD5WithRSA; break; case 'f': keyAlg = CSSM_ALGID_FEE; sigAlg = CSSM_ALGID_FEE_MD5; break; case 'F': keyAlg = CSSM_ALGID_FEE; sigAlg = CSSM_ALGID_FEE_SHA1; break; case 'e': keyAlg = CSSM_ALGID_FEE; sigAlg = CSSM_ALGID_SHA1WithECDSA; break; case 'E': keyAlg = CSSM_ALGID_ECDSA; sigAlg = CSSM_ALGID_SHA1WithECDSA; break; case '7': keyAlg = CSSM_ALGID_ECDSA; sigAlg = CSSM_ALGID_SHA256WithECDSA; break; case '8': keyAlg = CSSM_ALGID_ECDSA; sigAlg = CSSM_ALGID_SHA384WithECDSA; break; case '9': keyAlg = CSSM_ALGID_ECDSA; sigAlg = CSSM_ALGID_SHA512WithECDSA; break; case '2': keyAlg = CSSM_ALGID_RSA; sigAlg = CSSM_ALGID_SHA224WithRSA; break; case '6': keyAlg = CSSM_ALGID_RSA; sigAlg = CSSM_ALGID_SHA256WithRSA; break; case '3': keyAlg = CSSM_ALGID_RSA; sigAlg = CSSM_ALGID_SHA384WithRSA; break; case '5': keyAlg = CSSM_ALGID_RSA; sigAlg = CSSM_ALGID_SHA512WithRSA; break; default: usage(argv); } break; case 'k': keySizeInBits = atoi(&argv[arg][2]); break; default: usage(argv); } } /* connect to CL and CSP */ clHand = clStartup(); if(clHand == 0) { return 0; } cspHand = cspStartup(); if(cspHand == 0) { return 0; } /* subsequent errors to abort: to detach */ /* cook up an RSA key pair for the subject */ crtn = cspGenKeyPair(cspHand, keyAlg, SUBJ_KEY_LABEL, strlen(SUBJ_KEY_LABEL), keySizeInBits, &subjPubKey, CSSM_FALSE, // pubIsRef - should work both ways, but not yet CSSM_KEYUSE_VERIFY, CSSM_KEYBLOB_RAW_FORMAT_NONE, &subjPrivKey, CSSM_FALSE, // privIsRef CSSM_KEYUSE_SIGN, CSSM_KEYBLOB_RAW_FORMAT_NONE, CSSM_FALSE); if(crtn) { errorCount++; goto abort; } if(writeBlobs) { writeFile(SUBJ_PRIV_KEY_FILE, subjPrivKey.KeyData.Data, subjPrivKey.KeyData.Length); printf("...wrote %lu bytes to %s\n", subjPrivKey.KeyData.Length, SUBJ_PRIV_KEY_FILE); } /* and the root */ crtn = cspGenKeyPair(cspHand, keyAlg, ROOT_KEY_LABEL, strlen(ROOT_KEY_LABEL), keySizeInBits, &rootPubKey, CSSM_FALSE, // pubIsRef - should work both ways, but not yet CSSM_KEYUSE_VERIFY, CSSM_KEYBLOB_RAW_FORMAT_NONE, &rootPrivKey, CSSM_FALSE, // privIsRef CSSM_KEYUSE_SIGN, CSSM_KEYBLOB_RAW_FORMAT_NONE, CSSM_FALSE); if(crtn) { errorCount++; goto abort; } if(writeBlobs) { writeFile(ROOT_PRIV_KEY_FILE, rootPrivKey.KeyData.Data, rootPrivKey.KeyData.Length); printf("...wrote %lu bytes to %s\n", rootPrivKey.KeyData.Length, ROOT_PRIV_KEY_FILE); } if(compareKeyData(&rootPubKey, &subjPubKey)) { printf("**WARNING: Identical root and subj keys!\n"); } /* * Cook up various cert fields. * First, the RDNs for subject and issuer. */ rootName = CB_BuildX509Name(rootRdn, NUM_ROOT_NAMES); subjName = CB_BuildX509Name(subjRdn, NUM_SUBJ_NAMES); if((rootName == NULL) || (subjName == NULL)) { printf("CB_BuildX509Name failure"); errorCount++; goto abort; } /* not before/after in generalized time format */ notBefore = CB_BuildX509Time(0); notAfter = CB_BuildX509Time(10000); /* A KeyUsage extension for both certs */ exts[0].extnId = CSSMOID_KeyUsage; exts[0].critical = CSSM_FALSE; exts[0].format = CSSM_X509_DATAFORMAT_PARSED; keyUsage = CE_KU_DigitalSignature | CE_KU_KeyCertSign | CE_KU_KeyEncipherment | CE_KU_DataEncipherment; exts[0].value.parsedValue = &keyUsage; exts[0].BERvalue.Data = NULL; exts[0].BERvalue.Length = 0; /* BasicConstraints for root only */ exts[1].extnId = CSSMOID_BasicConstraints; exts[1].critical = CSSM_TRUE; exts[1].format = CSSM_X509_DATAFORMAT_PARSED; bc.cA = CSSM_TRUE; bc.pathLenConstraintPresent = CSSM_TRUE; bc.pathLenConstraint = 2; exts[1].value.parsedValue = &bc; exts[1].BERvalue.Data = NULL; exts[1].BERvalue.Length = 0; /* cook up root cert */ printf("Creating root cert...\n"); rawCert = CB_MakeCertTemplate(clHand, 0x12345678, // serial number rootName, rootName, notBefore, notAfter, &rootPubKey, sigAlg, NULL, // subjUniqueId NULL, // issuerUniqueId exts, // extensions 2); // numExtensions if(rawCert == NULL) { errorCount++; goto abort; } if(writeBlobs) { writeFile(ROOT_TBS_FILE_NAME, rawCert->Data, rawCert->Length); printf("...wrote %lu bytes to %s\n", rawCert->Length, ROOT_TBS_FILE_NAME); } /* Self-sign; this is a root cert */ crtn = CSSM_CSP_CreateSignatureContext(cspHand, sigAlg, NULL, // AccessCred &rootPrivKey, &signContext); if(crtn) { printError("CSSM_CSP_CreateSignatureContext", crtn); errorCount++; goto abort; } signedRootCert.Data = NULL; signedRootCert.Length = 0; crtn = CSSM_CL_CertSign(clHand, signContext, rawCert, // CertToBeSigned NULL, // SignScope 0, // ScopeSize, &signedRootCert); if(crtn) { printError("CSSM_CL_CertSign", crtn); errorCount++; goto abort; } crtn = CSSM_DeleteContext(signContext); if(crtn) { printError("CSSM_DeleteContext", crtn); errorCount++; goto abort; } appFreeCssmData(rawCert, CSSM_TRUE); if(writeBlobs) { writeFile(ROOT_CERT_FILE_NAME, signedRootCert.Data, signedRootCert.Length); printf("...wrote %lu bytes to %s\n", signedRootCert.Length, ROOT_CERT_FILE_NAME); } /* now a subject cert signed by the root cert */ printf("Creating subject cert...\n"); rawCert = CB_MakeCertTemplate(clHand, 0x8765, // serial number rootName, subjName, notBefore, notAfter, &subjPubKey, sigAlg, NULL, // subjUniqueId NULL, // issuerUniqueId exts, // extensions 1); // numExtensions if(rawCert == NULL) { errorCount++; goto abort; } if(writeBlobs) { writeFile(SUBJ_TBS_FILE_NAME, rawCert->Data, rawCert->Length); printf("...wrote %lu bytes to %s\n", rawCert->Length, SUBJ_TBS_FILE_NAME); } /* sign by root */ crtn = CSSM_CSP_CreateSignatureContext(cspHand, sigAlg, NULL, // AccessCred &rootPrivKey, &signContext); if(crtn) { printError("CSSM_CSP_CreateSignatureContext", crtn); errorCount++; goto abort; } signedSubjCert.Data = NULL; signedSubjCert.Length = 0; crtn = CSSM_CL_CertSign(clHand, signContext, rawCert, // CertToBeSigned NULL, // SignScope 0, // ScopeSize, &signedSubjCert); if(crtn) { printError("CSSM_CL_CertSign", crtn); errorCount++; goto abort; } crtn = CSSM_DeleteContext(signContext); if(crtn) { printError("CSSM_DeleteContext", crtn); errorCount++; goto abort; } appFreeCssmData(rawCert, CSSM_TRUE); if(writeBlobs) { writeFile(SUBJ_CERT_FILE_NAME, signedSubjCert.Data, signedSubjCert.Length); printf("...wrote %lu bytes to %s\n", signedSubjCert.Length, SUBJ_CERT_FILE_NAME); } /* Free the stuff we allocd to get here */ CB_FreeX509Name(rootName); CB_FreeX509Name(subjName); CB_FreeX509Time(notBefore); CB_FreeX509Time(notAfter); /* * Extract public keys from the two certs, verify. */ crtn = CSSM_CL_CertGetKeyInfo(clHand, &signedSubjCert, &extractSubjKey); if(crtn) { printError("CSSM_CL_CertGetKeyInfo", crtn); } else { /* compare key data - header is different. * Known header differences: * -- CspID - CSSM_CL_CertGetKeyInfo returns a key with NULL for * this field * -- Format. rootPubKey : 6 (CSSM_KEYBLOB_RAW_FORMAT_BSAFE) * extractRootKey : 1 (CSSM_KEYBLOB_RAW_FORMAT_PKCS1) * -- KeyAttr. rootPubKey : 0x20 (CSSM_KEYATTR_EXTRACTABLE) * extractRootKey : 0x0 */ if(!compareKeyData(extractSubjKey, &subjPubKey)) { printf("***CSSM_CL_CertGetKeyInfo(signedSubjCert) returned bad key data\n"); } if(extractSubjKey->KeyHeader.LogicalKeySizeInBits != subjPubKey.KeyHeader.LogicalKeySizeInBits) { printf("***EffectiveKeySizeInBits mismatch: extract %u subj %u\n", (unsigned)extractSubjKey->KeyHeader.LogicalKeySizeInBits, (unsigned)subjPubKey.KeyHeader.LogicalKeySizeInBits); } } crtn = CSSM_CL_CertGetKeyInfo(clHand, &signedRootCert, &extractRootKey); if(crtn) { printError("CSSM_CL_CertGetKeyInfo", crtn); } else { if(!compareKeyData(extractRootKey, &rootPubKey)) { printf("***CSSM_CL_CertGetKeyInfo(signedRootCert) returned bad key data\n"); } } /* * Verify: */ printf("Verifying certificates...\n"); /* * Verify root cert by root pub key, should succeed. */ if(verifyCert(clHand, cspHand, &signedRootCert, NULL, &rootPubKey, sigAlg, CSSM_OK, "Verify(root by root key)")) { errorCount++; /* continue */ } /* * Verify root cert by root cert, should succeed. */ if(verifyCert(clHand, cspHand, &signedRootCert, &signedRootCert, NULL, CSSM_ALGID_NONE, // sigAlg not used here CSSM_OK, "Verify(root by root cert)")) { errorCount++; /* continue */ } /* * Verify subject cert by root pub key, should succeed. */ if(verifyCert(clHand, cspHand, &signedSubjCert, NULL, &rootPubKey, sigAlg, CSSM_OK, "Verify(subj by root key)")) { errorCount++; /* continue */ } /* * Verify subject cert by root cert, should succeed. */ if(verifyCert(clHand, cspHand, &signedSubjCert, &signedRootCert, NULL, CSSM_ALGID_NONE, // sigAlg not used here CSSM_OK, "Verify(subj by root cert)")) { errorCount++; /* continue */ } /* * Verify subject cert by root cert AND key, should succeed. */ if(verifyCert(clHand, cspHand, &signedSubjCert, &signedRootCert, &rootPubKey, sigAlg, CSSM_OK, "Verify(subj by root cert and key)")) { errorCount++; /* continue */ } /* * Verify subject cert by extracted root pub key, should succeed. */ if(verifyCert(clHand, cspHand, &signedSubjCert, NULL, extractRootKey, sigAlg, CSSM_OK, "Verify(subj by extracted root key)")) { errorCount++; /* continue */ } /* * Verify subject cert by subject pub key, should fail. */ if(verifyCert(clHand, cspHand, &signedSubjCert, NULL, &subjPubKey, sigAlg, CSSMERR_CL_VERIFICATION_FAILURE, "Verify(subj by subj key)")) { errorCount++; /* continue */ } /* * Verify subject cert by subject cert, should fail. */ if(verifyCert(clHand, cspHand, &signedSubjCert, &signedSubjCert, NULL, CSSM_ALGID_NONE, // sigAlg not used here CSSMERR_CL_VERIFICATION_FAILURE, "Verify(subj by subj cert)")) { errorCount++; /* continue */ } /* * Verify erroneous subject cert by root pub key, should fail. */ badByte = genRand(1, signedSubjCert.Length - 1); signedSubjCert.Data[badByte] ^= 0x55; if(verifyCert(clHand, cspHand, &signedSubjCert, NULL, &rootPubKey, sigAlg, CSSMERR_CL_VERIFICATION_FAILURE, "Verify(bad subj by root key)")) { errorCount++; /* continue */ } /* free/delete certs and keys */ appFreeCssmData(&signedSubjCert, CSSM_FALSE); appFreeCssmData(&signedRootCert, CSSM_FALSE); cspFreeKey(cspHand, &rootPubKey); cspFreeKey(cspHand, &subjPubKey); /* These don't work because CSSM_CL_CertGetKeyInfo() gives keys with * a bogus GUID. This may be a problem with the Apple CSP... * cspFreeKey(cspHand, extractRootKey); cspFreeKey(cspHand, extractSubjKey); * * do it this way instead...*/ CSSM_FREE(extractRootKey->KeyData.Data); CSSM_FREE(extractSubjKey->KeyData.Data); /* need to do this regardless...*/ CSSM_FREE(extractRootKey); CSSM_FREE(extractSubjKey); abort: if(cspHand != 0) { CSSM_ModuleDetach(cspHand); } if(errorCount) { printf("Signer/Subject test failed with %d errors\n", errorCount); } else { printf("Signer/Subject test succeeded\n"); } return 0; }
int main(int argc, char **argv) { int arg; char *argp; int rtn; opParams op; if(argc < 2) { usage(argv); } memset(&op, 0, sizeof(opParams)); op.keySizeInBits = DEFAULT_KEY_SIZE_BITS; op.alg = CSSM_ALGID_RSA; op.swapKeyClass = CSSM_FALSE; op.rawSign = CSSM_FALSE; op.noPad = CSSM_FALSE; for(arg=2; arg<argc; arg++) { argp = argv[arg]; switch(argp[0]) { case 'a': if(argp[1] != '=') { usage(argv); } switch(argp[2]) { case 'r': op.alg = CSSM_ALGID_RSA; break; case 'd': op.alg = CSSM_ALGID_DSA; break; case 'e': op.alg = CSSM_ALGID_ECDSA; break; default: usage(argv); } break; case 'z': op.keySizeInBits = atoi(&argp[2]); break; case 'k': op.keyFileName = &argp[2]; break; case 'K': op.outKeyFileName = &argp[2]; break; case 'p': op.plainFileName = &argp[2]; break; case 'c': op.cipherFileName = &argp[2]; break; case 's': op.sigFileName = &argp[2]; break; case 'w': op.swapKeyClass = CSSM_TRUE; break; case 'r': op.rawSign = CSSM_TRUE; break; case 'P': op.noPad = CSSM_TRUE; break; case 'm': op.dsaParamFileIn = &argp[2]; break; case 'M': op.dsaParamFileOut = &argp[2]; break; case 'q': op.quiet = CSSM_TRUE; break; case 'b': if(argp[1] != '=') { usage(argv); } op.pubKeyFormat = parsePubKeyFormat(argp[2], argv); break; case 'B': if(argp[1] != '=') { usage(argv); } op.outPubKeyFormat = parsePubKeyFormat(argp[2], argv); break; case 'v': if(argp[1] != '=') { usage(argv); } switch(argp[2]) { case '1': op.privKeyFormat = CSSM_KEYBLOB_RAW_FORMAT_PKCS1; break; case '8': op.privKeyFormat = CSSM_KEYBLOB_RAW_FORMAT_PKCS8; break; case 's': op.privKeyFormat = CSSM_KEYBLOB_RAW_FORMAT_OPENSSH; break; case 'b': op.pubKeyFormat = CSSM_KEYBLOB_RAW_FORMAT_FIPS186; break; #if OPENSSL_ENABLE case 'o': op.privKeyFormat = CSSM_KEYBLOB_RAW_FORMAT_OPENSSL; break; #endif default: usage(argv); } break; case 'd': if(argp[1] != '=') { usage(argv); } switch(argp[2]) { case 's': op.digestAlg = CSSM_ALGID_SHA1; break; case '5': op.digestAlg = CSSM_ALGID_MD5; break; default: usage(argv); } break; case 'h': default: usage(argv); } } op.cspHand = cspDlDbStartup(CSSM_TRUE, NULL); if(op.cspHand == 0) { exit(1); } /* specify blob formats if user didn't */ if(op.pubKeyFormat == CSSM_KEYBLOB_RAW_FORMAT_NONE) { switch(op.alg) { case CSSM_ALGID_RSA: op.pubKeyFormat = CSSM_KEYBLOB_RAW_FORMAT_PKCS1; break; case CSSM_ALGID_DSA: case CSSM_ALGID_ECDSA: op.pubKeyFormat = CSSM_KEYBLOB_RAW_FORMAT_X509; break; default: printf("BRRZAP!\n"); exit(1); } } if(op.privKeyFormat == CSSM_KEYBLOB_RAW_FORMAT_NONE) { switch(op.alg) { case CSSM_ALGID_RSA: op.privKeyFormat = CSSM_KEYBLOB_RAW_FORMAT_PKCS8; break; case CSSM_ALGID_DSA: op.privKeyFormat = CSSM_KEYBLOB_RAW_FORMAT_FIPS186; break; case CSSM_ALGID_ECDSA: op.privKeyFormat = CSSM_KEYBLOB_RAW_FORMAT_OPENSSL; break; default: printf("BRRZAP!\n"); exit(1); } } switch(argv[1][0]) { case 'g': rtn = rt_generate(&op); break; case 'e': rtn = rt_encrypt(&op); break; case 'd': rtn = rt_decrypt(&op); break; case 's': rtn = rt_sign(&op); break; case 'v': rtn = rt_verify(&op); break; case 'S': op.alg = CSSM_ALGID_SHA1; rtn = rt_digest(&op); break; case 'M': op.alg = CSSM_ALGID_MD5; rtn = rt_digest(&op); break; case 'C': rtn = rt_convertPubKey(&op); break; default: usage(argv); exit(1); // fool the compiler } CSSM_ModuleDetach(op.cspHand); return rtn; }
int main(int argc, char **argv) { int arg; char *argp; int i; CSSM_CSP_HANDLE cspHand; CSSM_RETURN crtn; CSSM_KEY origPub; // we generate if !desSubj CSSM_KEY origPriv; CSSM_KEY_PTR origSess; // we generate if desSubj CSSM_KEY_PTR origEncrKey; // pts to origPub or origSess CSSM_KEY_PTR origDecrKey; // pts to origPriv or origSess CSSM_ALGORITHMS encrAlg; CSSM_ENCRYPT_MODE encrMode; CSSM_PADDING encrPad; int rtn = 0; CSSM_BOOL genRsaKey; uint32 maxPtextSize; CSSM_BOOL encrIsRef = CSSM_TRUE; CSSM_BOOL decrIsRef = CSSM_TRUE; CSSM_KEYBLOB_FORMAT wrapFormat = CSSM_KEYBLOB_WRAPPED_FORMAT_NONE; unsigned loop; /* user-specified vars */ unsigned loops = LOOPS_DEF; CSSM_BOOL pause = CSSM_FALSE; CSSM_BOOL doSymmWrap = CSSM_TRUE; CSSM_BOOL doAsymmWrap = CSSM_TRUE; CSSM_BOOL doNullWrap = CSSM_TRUE; CSSM_BOOL doSymmEncrOnly = CSSM_FALSE; CSSM_BOOL doAsymmEncrOnly = CSSM_FALSE; CSSM_BOOL wrapOnly = CSSM_FALSE; CSSM_BOOL quiet = CSSM_FALSE; CSSM_BOOL bareCsp = CSSM_TRUE; CSSM_BOOL forcePkcs = CSSM_FALSE; CSSM_BOOL refKeysOnly = CSSM_FALSE; #if PKCS_FORMAT_ENABLE CSSM_BOOL skipPkcs = CSSM_FALSE; #else CSSM_BOOL skipPkcs = CSSM_TRUE; #endif for(arg=1; arg<argc; arg++) { argp = argv[arg]; switch(argp[0]) { case 'S': doAsymmWrap = CSSM_FALSE; doNullWrap = CSSM_FALSE; break; case 'a': doSymmWrap = CSSM_FALSE; doNullWrap = CSSM_FALSE; break; case 'n': doSymmWrap = CSSM_FALSE; doAsymmWrap = CSSM_FALSE; break; case 'f': doAsymmEncrOnly = CSSM_TRUE; break; case 'd': // symmetric encrypt only option case 'e': // export option - avoids asymetric encrypt/decrypt doSymmEncrOnly = CSSM_TRUE; break; case 'l': loops = atoi(&argp[2]); break; case 'w': wrapOnly = CSSM_TRUE; break; case 'p': pause = CSSM_TRUE; break; case 'D': bareCsp = CSSM_FALSE; #if CSPDL_ALL_KEYS_ARE_REF refKeysOnly = CSSM_TRUE; #endif break; case 'k': forcePkcs = CSSM_TRUE; break; case 'K': #if PKCS7_FORMAT_ENABLE || PKCS8_FORMAT_ENABLE skipPkcs = CSSM_TRUE; #else skipPkcs = CSSM_FALSE; #endif break; case 'r': refKeysOnly = CSSM_TRUE; break; case 'q': quiet = CSSM_TRUE; break; default: usage(argv); } } #if 0 #if !PKCS_FORMAT_ENABLE if(skipPkcs) { if(doAsymmEncrOnly) { printf("Asymmetric keys can only be wrapped via PKCS; aborting\n"); usage(argv); } else if(!doSymmWrap) { printf("AsymmetricWrapping can only be done via PKCS; aborting\n"); usage(argv); } doSymmEncrOnly = CSSM_TRUE; doSymmWrap = CSSM_TRUE; doAsymmWrap = CSSM_FALSE; } #endif /* !PKCS_FORMAT_ENABLE */ #endif cspHand = cspDlDbStartup(bareCsp, NULL); if(cspHand == 0) { exit(1); } printf("Starting miniWrap; args: "); for(i=1; i<argc; i++) { printf("%s ", argv[i]); } printf("\n"); for(loop=1; ; loop++) { if((loop % LOOP_PAUSE) == 0) { if(!quiet) { printf("...loop %d\n", loop); } if(pause) { fpurge(stdin); printf("Hit CR to proceed: "); getchar(); } } /* mix up ref and raw keys - with X, we can wrap a raw key */ if(!refKeysOnly) { encrIsRef = (loop & 2) ? CSSM_TRUE : CSSM_FALSE; decrIsRef = (loop & 4) ? CSSM_TRUE : CSSM_FALSE; } /* first generate key to be wrapped */ if(!doAsymmEncrOnly && (doSymmEncrOnly || ((loop & 1) == 0))) { if(!quiet) { printf("...wrapping DES key (%s)\n", encrIsRef ? "ref" : "raw"); } origSess = cspGenSymKey(cspHand, CSSM_ALGID_DES, ENCR_USAGE_NAME, ENCR_USAGE_NAME_LEN, CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_DECRYPT, CSP_KEY_SIZE_DEFAULT, encrIsRef); if(origSess == NULL) { rtn = 1; goto testDone; } origDecrKey = origEncrKey = origSess; encrAlg = CSSM_ALGID_DES; encrMode = CSSM_ALGMODE_CBCPadIV8; encrPad = CSSM_PADDING_PKCS5; maxPtextSize = MAX_PTEXT_SIZE; // i.e., unlimited } else { origSess = NULL; } if(!doSymmEncrOnly && (doAsymmEncrOnly || ((loop & 1) == 1))) { if(!quiet) { printf("...wrapping RSA key (pub %s priv %s)\n", (encrIsRef ? "ref" : "raw"), (decrIsRef ? "ref" : "raw")); } crtn = cspGenKeyPair(cspHand, CSSM_ALGID_RSA, ENCR_USAGE_NAME, ENCR_USAGE_NAME_LEN, CSP_KEY_SIZE_DEFAULT, &origPub, encrIsRef, // pubIsRef CSSM_KEYUSE_ENCRYPT, CSSM_KEYBLOB_RAW_FORMAT_NONE, &origPriv, decrIsRef, // privIsRef CSSM_KEYUSE_DECRYPT, CSSM_KEYBLOB_RAW_FORMAT_NONE, CSSM_FALSE); // genSeed if(crtn) { rtn = 1; goto testDone; } origDecrKey = &origPriv; origEncrKey = &origPub; encrAlg = CSSM_ALGID_RSA; encrMode = CSSM_ALGMODE_NONE; encrPad = CSSM_PADDING_PKCS1; genRsaKey = CSSM_TRUE; maxPtextSize = origPriv.KeyHeader.LogicalKeySizeInBits / 8; // a weird BSAFE requirement which is not documented maxPtextSize -= 11; } else { genRsaKey = CSSM_FALSE; } /* now the tests, symmetric and/or asymmetric wrapping */ if(doSymmWrap) { CSSM_KEY_PTR wrapKey; if(!quiet) { printf(" ...Doing symmetric wrap\n"); } wrapKey = cspGenSymKey(cspHand, CSSM_ALGID_DES, WRAP_USAGE_NAME, WRAP_USAGE_NAME_LEN, /* for now, wrapping keys have to have keyuse_any */ /* CSSM_KEYUSE_WRAP | CSSM_KEYUSE_UNWRAP, */ WRAP_USAGE_ANY ? CSSM_KEYUSE_ANY : CSSM_KEYUSE_WRAP | CSSM_KEYUSE_UNWRAP, CSP_KEY_SIZE_DEFAULT, CSSM_TRUE); // FIXME - try both if(wrapKey == NULL) { rtn = 1; goto testDone; } if(forcePkcs) { /* symmetric wrapping key ==> PKCS7 */ wrapFormat = CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS7; } else { /* default */ wrapFormat = CSSM_KEYBLOB_WRAPPED_FORMAT_NONE; } if(doTest(cspHand, origEncrKey, origDecrKey, wrapKey, wrapKey, CSSM_ALGID_DES, // wrapAlg CSSM_ALGMODE_CBCPadIV8, // wrapMode wrapFormat, CSSM_PADDING_PKCS5, // wrapPad encrAlg, encrMode, encrPad, wrapOnly, maxPtextSize, quiet)) { rtn = 1; goto testDone; } cspFreeKey(cspHand, wrapKey); CSSM_FREE(wrapKey); // mallocd by cspGenSymKey wrapKey = NULL; } if(doAsymmWrap && !(RSA_WRAP_RESTRICTION && (origEncrKey != origDecrKey))) { /* skip wrapping asymmetric key with asymmetric key */ CSSM_KEY wrapPrivKey; CSSM_KEY wrapPubKey; if(!quiet) { printf(" ...Doing asymmetric wrap\n"); } crtn = cspGenKeyPair(cspHand, CSSM_ALGID_RSA, WRAP_USAGE_NAME, WRAP_USAGE_NAME_LEN, CSP_RSA_KEY_SIZE_DEFAULT, &wrapPubKey, CSSM_TRUE, // both are ref WRAP_USAGE_ANY ? CSSM_KEYUSE_ANY : CSSM_KEYUSE_WRAP, CSSM_KEYBLOB_RAW_FORMAT_NONE, &wrapPrivKey, CSSM_TRUE, // FIXME privIsRef WRAP_USAGE_ANY ? CSSM_KEYUSE_ANY : CSSM_KEYUSE_UNWRAP, CSSM_KEYBLOB_RAW_FORMAT_NONE, CSSM_FALSE); // genSeed if(crtn) { rtn = 1; goto testDone; } if(forcePkcs) { /* asymmetric wrapping key ==> PKCS8 */ wrapFormat = CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS8; } else { wrapFormat = CSSM_KEYBLOB_WRAPPED_FORMAT_NONE; } if(doTest(cspHand, origEncrKey, origDecrKey, &wrapPubKey, &wrapPrivKey, CSSM_ALGID_RSA, // wrapAlg CSSM_ALGMODE_NONE, // wrapMode wrapFormat, CSSM_PADDING_PKCS1, // wrapPad encrAlg, encrMode, encrPad, wrapOnly, maxPtextSize, quiet)) { rtn = 1; goto testDone; } cspFreeKey(cspHand, &wrapPubKey); cspFreeKey(cspHand, &wrapPrivKey); } //if(doNullWrap && (origDecrKey != origEncrKey)) { if(doNullWrap) { /* with X, we can do NULL wrap/unwrap of any key */ if(!quiet) { printf(" ...Doing NULL wrap\n"); } if(doTest(cspHand, origEncrKey, origDecrKey, NULL, NULL, CSSM_ALGID_NONE, // wrapAlg CSSM_ALGMODE_NONE, // wrapMode CSSM_KEYBLOB_WRAPPED_FORMAT_NONE, CSSM_PADDING_NONE, // wrapPad encrAlg, encrMode, encrPad, wrapOnly, maxPtextSize, quiet)) { rtn = 1; goto testDone; } } if(origSess != NULL) { cspFreeKey(cspHand, origSess); CSSM_FREE(origSess); } if(genRsaKey) { cspFreeKey(cspHand, &origPub); cspFreeKey(cspHand, &origPriv); } if(loops && (loop == loops)) { break; } } testDone: CSSM_ModuleDetach(cspHand); if((rtn == 0) && !quiet) { printf("%s test complete\n", argv[0]); } return rtn; }
OSStatus createPair(CFStringRef hostName,CFStringRef userName,SecKeychainRef keychainRef, uint32 keySizeInBits, CFDataRef *cert) { SecCertificateRef certRef = NULL; CSSM_DL_DB_HANDLE dlDbHand = {0, 0}; CSSM_CSP_HANDLE cspHand = 0; CSSM_TP_HANDLE tpHand = 0; CSSM_CL_HANDLE clHand = 0; CSSM_KEY_PTR pubKey = NULL; CSSM_KEY_PTR privKey = NULL; CSSM_DATA certData = {0, NULL}; char *hostStr = NULL; char *userStr = NULL; OSStatus ortn; CSSM_OID algOid = SR_CERT_SIGNATURE_ALG_OID; hostStr = secCopyCString(hostName); userStr = secCopyCString(userName); if (!hostStr || !userStr) // could not convert to UTF-8 { ortn = paramErr; goto xit; } // open keychain, connect to all the CDSA modules we'll need ortn = SecKeychainGetCSPHandle(keychainRef, &cspHand); if (ortn) goto xit; ortn = SecKeychainGetDLDBHandle(keychainRef, &dlDbHand); if (ortn) goto xit; tpHand = srTpStartup(); if (tpHand == 0) { ortn = ioErr; goto xit; } clHand = srClStartup(); if (clHand == 0) { ortn = ioErr; goto xit; } // generate key pair, private key stored in keychain ortn = generateKeyPair(cspHand, dlDbHand, SR_KEY_ALGORITHM, keySizeInBits, "FileVault Master Password Key", &pubKey, &privKey); if (ortn) goto xit; // generate the cert ortn = createRootCert(tpHand,clHand,cspHand,pubKey,privKey,hostStr,userStr, SR_CERT_SIGNATURE_ALGORITHM,&algOid,&certData); if (ortn) goto xit; // store the cert in the same DL/DB as the key pair [see SecCertificateCreateFromData] ortn = SecCertificateCreateFromData(&certData, CSSM_CERT_X_509v3, CSSM_CERT_ENCODING_DER, &certRef); if (ortn) goto xit; ortn = SecCertificateAddToKeychain(certRef, keychainRef); if (ortn) goto xit; // return the cert to caller *cert = CFDataCreate(NULL, certData.Data, certData.Length); // cleanup xit: if (certRef) CFRelease(certRef); if (certData.Data) free(certData.Data); if (hostStr) free(hostStr); if (userStr) free(userStr); if (tpHand) CSSM_ModuleDetach(tpHand); if (clHand) CSSM_ModuleDetach(clHand); if (pubKey) { CSSM_FreeKey(cspHand, NULL, // access cred pubKey, CSSM_FALSE); // delete APP_FREE(pubKey); } if (privKey) { CSSM_FreeKey(cspHand, NULL, // access cred privKey, CSSM_FALSE); // delete APP_FREE(privKey); } return ortn; }
/* * Find private key by label, modify its Label attr to be the * hash of the associated public key. */ static CSSM_RETURN setPubKeyHash( CSSM_CSP_HANDLE cspHand, CSSM_DL_DB_HANDLE dlDbHand, const CSSM_KEY *pubOrPrivKey, // to get hash; raw or ref/CSPDL const char *keyLabel) // look up by this { CSSM_QUERY query; CSSM_SELECTION_PREDICATE predicate; CSSM_DB_UNIQUE_RECORD_PTR record = NULL; CSSM_RETURN crtn; CSSM_DATA labelData; CSSM_HANDLE resultHand; labelData.Data = (uint8 *)keyLabel; labelData.Length = strlen(keyLabel) + 1; // incl. NULL query.RecordType = CSSM_DL_DB_RECORD_PRIVATE_KEY; query.Conjunctive = CSSM_DB_NONE; query.NumSelectionPredicates = 1; predicate.DbOperator = CSSM_DB_EQUAL; predicate.Attribute.Info.AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_STRING; predicate.Attribute.Info.Label.AttributeName = "Label"; predicate.Attribute.Info.AttributeFormat = CSSM_DB_ATTRIBUTE_FORMAT_BLOB; predicate.Attribute.Value = &labelData; query.SelectionPredicate = &predicate; query.QueryLimits.TimeLimit = 0; query.QueryLimits.SizeLimit = 1; query.QueryFlags = 0; /* build Record attribute with one attr */ CSSM_DB_RECORD_ATTRIBUTE_DATA recordAttrs; CSSM_DB_ATTRIBUTE_DATA attr; attr.Info.AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_STRING; attr.Info.Label.AttributeName = "Label"; attr.Info.AttributeFormat = CSSM_DB_ATTRIBUTE_FORMAT_BLOB; recordAttrs.DataRecordType = CSSM_DL_DB_RECORD_PRIVATE_KEY; recordAttrs.NumberOfAttributes = 1; recordAttrs.AttributeData = &attr; crtn = CSSM_DL_DataGetFirst(dlDbHand, &query, &resultHand, &recordAttrs, NULL, // hopefully optional ...theData, &record); /* abort only on success */ if(crtn != CSSM_OK) { sec_error("CSSM_DL_DataGetFirst: setPubKeyHash: can't find private key: %s", sec_errstr(crtn)); return crtn; } /* * If specified key is a ref key, do NULL unwrap for use with raw CSP. * If the CSPDL and SecurityServer support the key digest passthrough * this is unnecessary. */ CSSM_KEY rawKeyToDigest; if(pubOrPrivKey->KeyHeader.BlobType == CSSM_KEYBLOB_REFERENCE) { crtn = refKeyToRaw(cspHand, pubOrPrivKey, &rawKeyToDigest); if(crtn) { sec_error("setPubKeyHash: Error converting public key to raw format: %s", sec_errstr(crtn)); return crtn; } } else { /* use as is */ rawKeyToDigest = *pubOrPrivKey; } /* connect to raw CSP */ CSSM_CSP_HANDLE rawCspHand = srCspStartup(CSSM_TRUE); if(rawCspHand == 0) { printf("***Error connecting to raw CSP; aborting.\n"); return -1; } /* calculate hash of pub key from private or public part */ CSSM_DATA_PTR keyDigest = NULL; CSSM_CC_HANDLE ccHand; crtn = CSSM_CSP_CreatePassThroughContext(rawCspHand, &rawKeyToDigest, &ccHand); if(ccHand == 0) { sec_error("CSSM_CSP_CreatePassThroughContext: Error calculating public key hash. Aborting: %s", sec_errstr(crtn)); return -1; } crtn = CSSM_CSP_PassThrough(ccHand, CSSM_APPLECSP_KEYDIGEST, NULL, (void **)&keyDigest); if(crtn) { sec_error("CSSM_CSP_PassThrough(PUBKEYHASH): Error calculating public key hash. Aborting: %s", sec_errstr(crtn)); return crtn; } if(pubOrPrivKey->KeyHeader.BlobType == CSSM_KEYBLOB_REFERENCE) { /* created in refKeyToRaw().... */ CSSM_FreeKey(cspHand, NULL, &rawKeyToDigest, CSSM_FALSE); } CSSM_DeleteContext(ccHand); CSSM_ModuleDetach(rawCspHand); /* * Replace Label attr data with hash. * NOTE: the module which allocated this attribute data - a DL - * was loaded and attached by the Sec layer, not by us. Thus * we can't use the memory allocator functions *we* used when * attaching to the CSPDL - we have to use the ones * which the Sec layer registered with the DL. */ CSSM_API_MEMORY_FUNCS memFuncs; crtn = CSSM_GetAPIMemoryFunctions(dlDbHand.DLHandle, &memFuncs); if(crtn) { sec_error("CSSM_GetAPIMemoryFunctions(DLHandle): Error: %s", sec_errstr(crtn)); /* oh well, leak and continue */ } else { memFuncs.free_func(attr.Value->Data, memFuncs.AllocRef); memFuncs.free_func(attr.Value, memFuncs.AllocRef); } attr.Value = keyDigest; /* modify key attributes */ crtn = CSSM_DL_DataModify(dlDbHand, CSSM_DL_DB_RECORD_PRIVATE_KEY, record, &recordAttrs, NULL, // DataToBeModified CSSM_DB_MODIFY_ATTRIBUTE_REPLACE); if(crtn) { sec_error("CSSM_DL_DataModify(PUBKEYHASH): Error setting public key hash. Aborting: %s", sec_errstr(crtn)); return crtn; } crtn = CSSM_DL_DataAbortQuery(dlDbHand, resultHand); if(crtn) { sec_error("CSSM_DL_DataAbortQuery: Error while stopping query: %s", sec_errstr(crtn)); /* let's keep going in this case */ } crtn = CSSM_DL_FreeUniqueRecord(dlDbHand, record); if(crtn) { sec_error("CSSM_DL_FreeUniqueRecord: Error while freeing record: %s", sec_errstr(crtn)); /* let's keep going in this case */ crtn = CSSM_OK; } /* free resources */ if (keyDigest) { srAppFree(keyDigest->Data, NULL); srAppFree(keyDigest, NULL); } return CSSM_OK; }