X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/SecurityTests/clxutils/idTool/idTool.cpp diff --git a/SecurityTests/clxutils/idTool/idTool.cpp b/SecurityTests/clxutils/idTool/idTool.cpp new file mode 100644 index 00000000..e861388e --- /dev/null +++ b/SecurityTests/clxutils/idTool/idTool.cpp @@ -0,0 +1,439 @@ +/* + * Examine and test a keychain's identity + */ +#include +#include +#include +#include +#include +#include +#include +#include + +typedef enum { + KC_Nop, + KC_GetInfo, + KC_LockKC, + KC_UnlockKC, + KC_SignVfy, + KC_KeyCertInfo +} KcOp; + +static void usage(char **argv) +{ + printf("Usage: %s keychain|- cmd [options]\n", argv[0]); + printf("Command:\n"); + printf(" i get KC info\n"); + printf(" k get key and cert info\n"); + printf(" l lock\n"); + printf(" u unlock\n"); + printf(" s sign and verify\n"); + printf("Options:\n"); + printf(" p=passphrase\n"); + printf("Specifying '-' for keychain means NULL, default\n"); + exit(1); +} + +static void showError( + OSStatus ortn, + const char *msg) +{ + const char *errStr = NULL; + switch(ortn) { + case errSecItemNotFound: + errStr = "errSecItemNotFound"; break; + case errSecNoSuchKeychain: + errStr = "errSecNoSuchKeychain"; break; + case errSecNotAvailable: + errStr = "errSecNotAvailable"; break; + /* more? */ + default: + if(ortn < (CSSM_BASE_ERROR + + (CSSM_ERRORCODE_MODULE_EXTENT * 8))) { + /* assume CSSM error */ + errStr = cssmErrToStr(ortn); + } + break; + + } + if(errStr) { + printf("***Error on %s: %s\n", msg, errStr); + } + else { + printf("***Error on %s: %d(d)\n", msg, (int)ortn); + } +} + +static void printDataAsHex( + const CSSM_DATA *d, + unsigned maxToPrint = 0) // optional, 0 means print it all +{ + unsigned i; + bool more = false; + uint32 len = d->Length; + uint8 *cp = d->Data; + + if((maxToPrint != 0) && (len > maxToPrint)) { + len = maxToPrint; + more = true; + } + for(i=0; iKeyHeader); + printf(" Key Blob : "); + printDataAsHex(&cssmKey->KeyData, 8); + } + + /* and the cert */ + CSSM_DATA certData; + OSStatus ortn = SecCertificateGetData(certRef, &certData); + if(ortn) { + showError(ortn, "SecCertificateGetData"); + return ortn; + } + printf("\nCertificate :\n"); + printCert((unsigned char *)certData.Data, (unsigned)certData.Length, + CSSM_TRUE); + return noErr; +} + +#define SIG_ALG CSSM_ALGID_SHA1WithRSA + +static OSStatus signVfy( + SecCertificateRef certRef, + SecKeyRef keyRef, + CSSM_KEY_PTR cssmKey, + CSSM_CSP_HANDLE cspHand) +{ + uint8 someData[] = {0,1,2,3,4,5,6,7,8}; + CSSM_DATA ptext = {sizeof(someData), someData}; + CSSM_DATA sig = {0, NULL}; + CSSM_RETURN crtn; + + /* sign with CSPDL */ + crtn = cspSign(cspHand, SIG_ALG, cssmKey, &ptext, &sig); + if(crtn) { + printf("Error signing with private key\n"); + return crtn; + } + + /* attach to CL */ + CSSM_CL_HANDLE clHand = clStartup(); + if(clHand == 0) { + printf("***Error attaching to CL\n"); + return ioErr; + } + + /* get the public key from the cert */ + CSSM_DATA certData; + OSStatus ortn = SecCertificateGetData(certRef, &certData); + if(ortn) { + showError(ortn, "SecCertificateGetData"); + return ortn; + } + CSSM_KEY_PTR pubKey = NULL; + crtn = CSSM_CL_CertGetKeyInfo(clHand, &certData, &pubKey); + if(crtn) { + printError("CSSM_CL_CertGetKeyInfo", crtn); + return crtn; + } + + /* attach to raw CSP */ + CSSM_CSP_HANDLE rawCspHand = cspStartup(); + if(rawCspHand == 0) { + printf("***Error attaching to raw CSP\n"); + return ioErr; + } + + /* verify with raw CSP and raw public key */ + crtn = cspSigVerify(rawCspHand, SIG_ALG, pubKey, &ptext, + &sig, CSSM_OK); + if(crtn) { + printf("Error verifying with public key\n"); + return crtn; + } + + /* free everything */ + CSSM_ModuleDetach(rawCspHand); + CSSM_ModuleDetach(clHand); + printf("...sign with private key, vfy with cert OK\n"); + return noErr; +} + +/* get cert and private key (in Sec and CSSM form) from identity */ +static OSStatus getKeyCert( + SecIdentityRef idRef, + SecCertificateRef &certRef, // RETURNED + SecKeyRef &keyRef, // private key, RETURNED + CSSM_KEY_PTR &cssmKey) // private key, RETURNED +{ + OSStatus ortn = SecIdentityCopyCertificate(idRef, &certRef); + if(ortn) { + showError(ortn, "SecIdentityCopyCertificate"); + return ortn; + } + ortn = SecIdentityCopyPrivateKey(idRef, &keyRef); + if(ortn) { + showError(ortn, "SecIdentityCopyPrivateKey"); + return ortn; + } + ortn = SecKeyGetCSSMKey(keyRef, (const CSSM_KEY **)&cssmKey); + if(ortn) { + showError(ortn, "SecKeyGetCSSMKey"); + } + return ortn; +} + +int main(int argc, char **argv) +{ + SecKeychainRef kcRef = nil; + OSStatus ortn; + int arg; + char *argp; + + /* user-spec'd variables */ + KcOp op = KC_Nop; + char *pwd = NULL; + char *kcName; + + if(argc < 3) { + usage(argv); + } + kcName = argv[1]; + if(!strcmp("-", kcName)) { + /* null - no open */ + kcName = NULL; + } + switch(argv[2][0]) { + case 'i': + op = KC_GetInfo; break; + case 'l': + op = KC_LockKC; break; + case 'u': + op = KC_UnlockKC; break; + case 's': + op = KC_SignVfy; break; + case 'k': + op = KC_KeyCertInfo; break; + default: + usage(argv); + } + for(arg=3; arg