+++ /dev/null
-/*
- * dotMacTool.cpp - .mac TP exerciser
- */
-
-#include <Security/Security.h>
-#include <Security/SecKeyPriv.h>
-#include <security_cdsa_utils/cuCdsaUtils.h>
-#include <security_cdsa_utils/cuFileIo.h>
-#include <security_cdsa_utils/cuPem.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-//#include <security_dotmac_tp/dotMacTp.h>
-#include <dotMacTp.h>
-#include <security_cdsa_utils/cuPrintCert.h>
-
-#include "keyPicker.h"
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
-
-#define USER_DEFAULT "dmitchtest@mac.com"
-#define PWD_DEF "123456"
-
-static void usage(char **argv)
-{
- printf("usage: %s op [options]\n", argv[0]);
- printf("Op:\n");
- printf(" g generate identity cert\n");
- printf(" G generate email signing cert\n");
- printf(" e generate email encrypting cert\n");
- printf(" l lookup cert (requires -f)\n");
- printf(" L lookup identity cert (via -u)\n");
- printf(" M lookup email signing cert (via -u)\n");
- printf(" N lookup encrypting cert (via -u)\n");
- printf("Options:\n");
- printf(" -g Generate keypair\n");
- printf(" -p pick key pair from existing\n");
- printf(" -u username Default = %s\n", USER_DEFAULT);
- printf(" -Z password Specify password immediately\n");
- printf(" -z Use default password %s\n", PWD_DEF);
- printf(" -k keychain Source/destination of keys and certs\n");
- printf(" -c filename Write CSR to filename\n");
- printf(" -C filename Use existing CSR (no keygen)\n");
- printf(" -f refIdFile RefId file for cert lookup\n");
- printf(" -n Do NOT post the CSR to the .mac server\n");
- printf(" -H hostname Alternate .mac server host name (default %s)\n",
- DOT_MAC_SIGN_HOST_NAME);
- printf(" -o outFile Write output cert or refId (if any) to outFile\n");
- printf(" -r Renew (default is new)\n");
- printf(" -M Pause for MallocDebug\n");
- printf(" -q Quiet\n");
- printf(" -v Verbose\n");
- printf(" -h Usage\n");
- exit(1);
-}
-
-static CSSM_VERSION vers = {2, 0};
-
-static CSSM_API_MEMORY_FUNCS memFuncs = {
- cuAppMalloc,
- cuAppFree,
- cuAppRealloc,
- cuAppCalloc,
- NULL
- };
-
-static CSSM_TP_HANDLE dotMacStartup()
-{
- CSSM_TP_HANDLE tpHand;
- CSSM_RETURN crtn;
-
- if(cuCssmStartup() == CSSM_FALSE) {
- return 0;
- }
- crtn = CSSM_ModuleLoad(&gGuidAppleDotMacTP,
- CSSM_KEY_HIERARCHY_NONE,
- NULL, // eventHandler
- NULL); // AppNotifyCallbackCtx
- if(crtn) {
- cuPrintError("CSSM_ModuleLoad(DotMacTP)", crtn);
- return 0;
- }
- crtn = CSSM_ModuleAttach (&gGuidAppleDotMacTP,
- &vers,
- &memFuncs, // memFuncs
- 0, // SubserviceID
- CSSM_SERVICE_TP, // SubserviceFlags
- 0, // AttachFlags
- CSSM_KEY_HIERARCHY_NONE,
- NULL, // FunctionTable
- 0, // NumFuncTable
- NULL, // reserved
- &tpHand);
- if(crtn) {
- cuPrintError("CSSM_ModuleAttach(DotMacTP)", crtn);
- return 0;
- }
- else {
- return tpHand;
- }
-}
-
-/* print text, safely */
-static void snDumpText(
- const unsigned char *rcvBuf,
- unsigned len)
-{
- char *cp = (char *)rcvBuf;
- unsigned i;
- char c;
-
- for(i=0; i<len; i++) {
- c = *cp++;
- if(c == '\0') {
- break;
- }
- switch(c) {
- case '\n':
- printf("\\n\n"); // graphic and liternal newline
- break;
- case '\r':
- printf("\\r\n");
- break;
- default:
- if(isprint(c) && (c != '\n')) {
- printf("%c", c);
- }
- else {
- printf("<%02X>", ((unsigned)c) & 0xff);
- }
- break;
- }
-
- }
-}
-
-static OSStatus genKeyPair(
- SecKeychainRef kcRef, // NULL means the default list
- SecKeyRef *pubKey, // RETURNED
- SecKeyRef *privKey) // RETURNED
-{
- OSStatus ortn;
-
- ortn = SecKeyCreatePair(kcRef,
- DOT_MAC_KEY_ALG,
- DOT_MAC_KEY_SIZE,
- 0, // context handle
- /* public key usage and attrs */
- CSSM_KEYUSE_ANY,
- CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_PERMANENT | CSSM_KEYATTR_EXTRACTABLE,
- /* private key usage and attrs */
- CSSM_KEYUSE_ANY,
- CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_PERMANENT | CSSM_KEYATTR_EXTRACTABLE |
- CSSM_KEYATTR_SENSITIVE,
- NULL, // initial access
- pubKey,
- privKey);
- if(ortn) {
- cssmPerror("SecKeyCreatePair", ortn);
- }
- return ortn;
-}
-
-/* Lookup via ReferenceID, obtained from CSSM_TP_SubmitCredRequest() */
-OSStatus doLookupViaRefId(
- CSSM_TP_HANDLE tpHand,
- unsigned char *refId,
- unsigned refIdLen,
- char *outFile,
- bool verbose)
-{
- CSSM_DATA refIdData = { refIdLen, refId };
- sint32 EstimatedTime;
- CSSM_BOOL ConfirmationRequired;
- CSSM_TP_RESULT_SET_PTR resultSet = NULL;
- CSSM_RETURN crtn;
-
- crtn = CSSM_TP_RetrieveCredResult(tpHand, &refIdData, NULL,
- &EstimatedTime, &ConfirmationRequired, &resultSet);
- if(crtn) {
- cssmPerror("CSSM_TP_RetrieveCredResult", crtn);
- return crtn;
- }
- if(resultSet == NULL) {
- printf("***CSSM_TP_RetrieveCredResult OK, but no result set\n");
- return -1;
- }
- if(resultSet->NumberOfResults != 1) {
- printf("***CSSM_TP_RetrieveCredResult OK, NumberOfResults (%u)\n",
- (unsigned)resultSet->NumberOfResults);
- return -1;
- }
- if(resultSet->Results == NULL) {
- printf("***CSSM_TP_RetrieveCredResult OK, but empty result set\n");
- return -1;
- }
- CSSM_DATA_PTR certData = (CSSM_DATA_PTR)resultSet->Results;
-
- printf("...cert retrieval complete\n");
- if(outFile) {
- if(!writeFile(outFile, certData->Data, certData->Length)) {
- printf("...%lu bytes of cert data written to %s\n",
- certData->Length, outFile);
- }
- else {
- printf("***Error writing cert to %s\n", outFile);
- crtn = ioErr;
- }
- }
- else if(verbose) {
- unsigned char *der;
- unsigned derLen;
- if(pemDecode(certData->Data, certData->Length, &der, &derLen)) {
- printf("***Error PEM decoding returned cert\n");
- }
- else {
- printCert(der, derLen, CSSM_FALSE);
- free(der);
- }
- }
- return noErr;
-}
-
-/*
-* Lookup via user name, a greatly simplified form of CSSM_TP_SubmitCredRequest()
-*/
-OSStatus doLookupViaUserName(
- CSSM_TP_HANDLE tpHand,
- const CSSM_OID *opOid,
- const char *userName,
- const char *hostName, // optional
- char *outFile,
- bool verbose)
-{
- CSSM_APPLE_DOTMAC_TP_CERT_REQUEST certReq;
- CSSM_TP_AUTHORITY_ID tpAuthority;
- CSSM_TP_AUTHORITY_ID *tpAuthPtr = NULL;
- CSSM_NET_ADDRESS tpNetAddrs;
- CSSM_TP_REQUEST_SET reqSet;
- CSSM_FIELD policyField;
- CSSM_DATA certData = {0, NULL};
- sint32 estTime;
- CSSM_TP_CALLERAUTH_CONTEXT callerAuth;
-
- memset(&certReq, 0, sizeof(certReq));
- certReq.userName.Data = (uint8 *)userName;
- certReq.userName.Length = strlen(userName);
- if(hostName != NULL) {
- tpAuthority.AuthorityCert = NULL;
- tpAuthority.AuthorityLocation = &tpNetAddrs;
- tpNetAddrs.AddressType = CSSM_ADDR_NAME;
- tpNetAddrs.Address.Data = (uint8 *)hostName;
- tpNetAddrs.Address.Length = strlen(hostName);
- tpAuthPtr = &tpAuthority;
- };
-
- certReq.version = CSSM_DOT_MAC_TP_REQ_VERSION;
- reqSet.NumberOfRequests = 1;
- reqSet.Requests = &certReq;
- policyField.FieldOid = *opOid;
- policyField.FieldValue.Data = NULL;
- policyField.FieldValue.Length = 0;
- memset(&callerAuth, 0, sizeof(callerAuth));
- callerAuth.Policy.NumberOfPolicyIds = 1;
- callerAuth.Policy.PolicyIds = &policyField;
-
- CSSM_RETURN crtn = CSSM_TP_SubmitCredRequest (tpHand,
- tpAuthPtr,
- CSSM_TP_AUTHORITY_REQUEST_CERTLOOKUP,
- &reqSet, // const CSSM_TP_REQUEST_SET *RequestInput,
- &callerAuth,
- &estTime, // sint32 *EstimatedTime,
- &certData); // CSSM_DATA_PTR ReferenceIdentifier
-
- if(crtn) {
- cssmPerror("CSSM_TP_SubmitCredRequest(lookup)", crtn);
- return crtn;
- }
-
- printf("...cert lookup complete\n");
- if(outFile) {
- if(!writeFile(outFile, certData.Data, certData.Length)) {
- printf("...%lu bytes of cert data written to %s\n",
- certData.Length, outFile);
- }
- else {
- printf("***Error writing cert to %s\n", outFile);
- crtn = ioErr;
- }
- }
- if(verbose) {
- /* This one returns the cert in DER format, we might revisit that */
- printCert(certData.Data, certData.Length, CSSM_FALSE);
- }
- return crtn;
-}
-
-#define FULL_EMAIL_ADDRESS 1
-
-int main(int argc, char **argv)
-{
- CSSM_RETURN crtn;
- CSSM_TP_AUTHORITY_ID tpAuthority;
- CSSM_TP_AUTHORITY_ID *tpAuthPtr = NULL;
- CSSM_NET_ADDRESS tpNetAddrs;
- CSSM_APPLE_DOTMAC_TP_CERT_REQUEST certReq;
- CSSM_TP_REQUEST_SET reqSet;
- CSSM_CSP_HANDLE cspHand = 0;
- CSSM_X509_TYPE_VALUE_PAIR tvp;
- char pwdBuf[1000];
- CSSM_TP_CALLERAUTH_CONTEXT callerAuth;
- sint32 estTime;
- CSSM_DATA refId = {0, NULL};
- OSStatus ortn;
- SecKeyRef pubKeyRef = NULL;
- SecKeyRef privKeyRef = NULL;
- const CSSM_KEY *privKey = NULL;
- const CSSM_KEY *pubKey = NULL;
- SecKeychainRef kcRef = NULL;
- CSSM_FIELD policyField;
-
- /* user-spec'd variables */
- bool genKeys = false;
- bool pickKeys = false;
- char *keychainName = NULL;
- char *csrOutName = NULL;
- char *csrInName = NULL;
- const char *userName = USER_DEFAULT;
- char *password = NULL;
- char *hostName = NULL;
- bool doNotPost = false;
- bool doRenew = false;
- const CSSM_OID *opOid = NULL;
- char *outFile = NULL;
- bool quiet = false;
- bool verbose = false;
- bool lookupViaRefId = false;
- bool lookupViaUserName = false;
- char *refIdFile = NULL;
- bool doPause = false;
-
- if(argc < 2) {
- usage(argv);
- }
- switch(argv[1][0]) {
- case 'L':
- lookupViaUserName = true;
- /* drop thru */
- case 'g':
- opOid = &CSSMOID_DOTMAC_CERT_REQ_IDENTITY;
- break;
-
- case 'M':
- lookupViaUserName = true;
- /* drop thru */
- case 'G':
- opOid = &CSSMOID_DOTMAC_CERT_REQ_EMAIL_SIGN;
- break;
-
- case 'N':
- lookupViaUserName = true;
- /* drop thru */
- case 'e':
- opOid = &CSSMOID_DOTMAC_CERT_REQ_EMAIL_ENCRYPT;
- break;
-
- case 'l':
- lookupViaRefId = true;
- break;
- default:
- usage(argv);
- }
-
- extern char *optarg;
- extern int optind;
- optind = 2;
- int arg;
- while ((arg = getopt(argc, argv, "gpk:c:u:Z:H:nzrC:o:hf:Mqv")) != -1) {
- switch (arg) {
- case 'g':
- genKeys = true;
- break;
- case 'p':
- pickKeys = true;
- break;
- case 'u':
- userName = optarg;
- break;
- case 'Z':
- password = optarg;
- break;
- case 'z':
- password = (char *)PWD_DEF;
- break;
- case 'k':
- keychainName = optarg;
- break;
- case 'c':
- csrOutName = optarg;
- break;
- case 'C':
- csrInName = optarg;
- break;
- case 'H':
- hostName = optarg;
- break;
- case 'n':
- doNotPost = true;
- break;
- case 'r':
- doRenew = true;
- break;
- case 'o':
- outFile = optarg;
- break;
- case 'f':
- refIdFile = optarg;
- break;
- case 'M':
- doPause = true;
- break;
- case 'v':
- verbose = true;
- break;
- case 'q':
- quiet = true;
- break;
- case 'h':
- usage(argv);
- }
- }
-
- if(doPause) {
- fpurge(stdin);
- printf("Pausing for MallocDebug attach; CR to continue: ");
- getchar();
- }
-
- CSSM_TP_HANDLE tpHand = dotMacStartup();
- if(tpHand == 0) {
- printf("Error attaching to the .mac TP. Check your MDS file.\n");
- exit(1);
- }
-
- if(lookupViaRefId) {
- if(refIdFile == NULL) {
- printf("I need a refIdFile to do a lookup.\n");
- usage(argv);
- }
- unsigned char *refId;
- unsigned refIdLen;
- int irtn = readFile(refIdFile, &refId, &refIdLen);
- if(irtn) {
- printf("***Error reading refId from %s. Aborting.\n", refIdFile);
- exit(1);
- }
- ortn = doLookupViaRefId(tpHand, refId, refIdLen, outFile, verbose);
- free(refId);
- goto done;
- }
- if(lookupViaUserName) {
- ortn = doLookupViaUserName(tpHand, opOid, userName, hostName, outFile, verbose);
- goto done;
- }
- if(!pickKeys && !genKeys && (csrInName == NULL)) {
- printf("***You must specify either the -p (pick keys) or -g (generate keys)"
- " arguments, or provide a CSR (-C).\n");
- exit(1);
- }
-
- memset(&certReq, 0, sizeof(certReq));
-
- /* all of the subsequest argument are superfluous for lookupViaUserName, except for
- * the user name itself, which has a default */
- if(keychainName != NULL) {
- /* pick a keychain (optional) */
- ortn = SecKeychainOpen(keychainName, &kcRef);
- if(ortn) {
- cssmPerror("SecKeychainOpen", ortn);
- exit(1);
- }
-
- /* make sure it's there since a successful SecKeychainOpen proves nothing */
- SecKeychainStatus kcStat;
- ortn = SecKeychainGetStatus(kcRef, &kcStat);
- if(ortn) {
- cssmPerror("SecKeychainGetStatus", ortn);
- goto done;
- }
- }
-
- if(password == NULL) {
- const char *pwdp = getpass("Enter .mac password: ");
- if(pwdp == NULL) {
- printf("Aboerting.\n");
- ortn = paramErr;
- goto done;
- }
- memmove(pwdBuf, pwdp, strlen(pwdp) + 1);
- password = pwdBuf;
- }
- certReq.password.Data = (uint8 *)password;
- certReq.password.Length = strlen(password);
- certReq.userName.Data = (uint8 *)userName;
- certReq.userName.Length = strlen(userName);
-
- if(csrInName) {
- unsigned len;
- if(readFile(csrInName, &certReq.csr.Data, &len)) {
- printf("***Error reading CSR from %s. Aborting.\n", csrInName);
- exit(1);
- }
- certReq.csr.Length = len;
- certReq.flags |= CSSM_DOTMAC_TP_EXIST_CSR;
- }
- else {
- /*
- * All the stuff the TP needs to actually generate a CSR.
- *
- * Get a key pair, somehow.
- */
- if(genKeys) {
- ortn = genKeyPair(kcRef, &pubKeyRef, &privKeyRef);
- }
- else {
- ortn = keyPicker(kcRef, &pubKeyRef, &privKeyRef);
- }
- if(ortn) {
- printf("Can't proceed without a keypair. Aborting.\n");
- exit(1);
- }
- ortn = SecKeyGetCSSMKey(pubKeyRef, &pubKey);
- if(ortn) {
- cssmPerror("SecKeyGetCSSMKey", ortn);
- goto done;
- }
- ortn = SecKeyGetCSSMKey(privKeyRef, &privKey);
- if(ortn) {
- cssmPerror("SecKeyGetCSSMKey", ortn);
- goto done;
- }
- ortn = SecKeyGetCSPHandle(privKeyRef, &cspHand);
- if(ortn) {
- cssmPerror("SecKeyGetCSPHandle", ortn);
- goto done;
- }
-
- /* CSSM_X509_TYPE_VALUE_PAIR - one pair for now */
- // tvp.type = CSSMOID_EmailAddress;
- tvp.type = CSSMOID_CommonName;
- tvp.valueType = BER_TAG_PRINTABLE_STRING;
- #if FULL_EMAIL_ADDRESS
- {
- unsigned nameLen = strlen(userName);
- tvp.value.Data = (uint8 *)malloc(nameLen + strlen("@mac.com") + 1);
- strcpy((char *)tvp.value.Data, userName);
- strcpy((char *)tvp.value.Data + nameLen, "@mac.com");
- tvp.value.Length = strlen((char *)tvp.value.Data);
- }
- #else
- tvp.value.Data = (uint8 *)userName;
- tvp.value.Length = strlen(userName);
- #endif
- }
- /* set up args for CSSM_TP_SubmitCredRequest */
- if(hostName != NULL) {
- tpAuthority.AuthorityCert = NULL;
- tpAuthority.AuthorityLocation = &tpNetAddrs;
- tpNetAddrs.AddressType = CSSM_ADDR_NAME;
- tpNetAddrs.Address.Data = (uint8 *)hostName;
- tpNetAddrs.Address.Length = strlen(hostName);
- tpAuthPtr = &tpAuthority;
- };
-
- certReq.version = CSSM_DOT_MAC_TP_REQ_VERSION;
- if(!csrInName) {
- certReq.cspHand = cspHand;
- certReq.clHand = cuClStartup();
- certReq.numTypeValuePairs = 1;
- certReq.typeValuePairs = &tvp;
- certReq.publicKey = (CSSM_KEY_PTR)pubKey;
- certReq.privateKey = (CSSM_KEY_PTR)privKey;
- }
- if(doNotPost) {
- certReq.flags |= CSSM_DOTMAC_TP_DO_NOT_POST;
- }
- if(csrOutName != NULL) {
- certReq.flags |= CSSM_DOTMAC_TP_RETURN_CSR;
- }
- if(doRenew) {
- certReq.flags |= CSSM_DOTMAC_TP_SIGN_RENEW;
- }
-
- reqSet.NumberOfRequests = 1;
- reqSet.Requests = &certReq;
-
- policyField.FieldOid = *opOid;
- policyField.FieldValue.Data = NULL;
- policyField.FieldValue.Length = 0;
- memset(&callerAuth, 0, sizeof(callerAuth));
- callerAuth.Policy.NumberOfPolicyIds = 1;
- callerAuth.Policy.PolicyIds = &policyField;
- if(!csrInName) {
- ortn = SecKeyGetCredentials(privKeyRef,
- CSSM_ACL_AUTHORIZATION_SIGN,
- kSecCredentialTypeDefault,
- const_cast<const CSSM_ACCESS_CREDENTIALS **>(&callerAuth.CallerCredentials));
- if(ortn) {
- cssmPerror("SecKeyGetCredentials", crtn);
- goto done;
- }
- }
-
- crtn = CSSM_TP_SubmitCredRequest (tpHand,
- tpAuthPtr,
- CSSM_TP_AUTHORITY_REQUEST_CERTISSUE, // CSSM_TP_AUTHORITY_REQUEST_TYPE
- &reqSet, // const CSSM_TP_REQUEST_SET *RequestInput,
- &callerAuth,
- &estTime, // sint32 *EstimatedTime,
- &refId); // CSSM_DATA_PTR ReferenceIdentifier
- switch(crtn) {
- case CSSM_OK:
- case CSSMERR_APPLE_DOTMAC_REQ_QUEUED:
- {
- /*
- * refId should be a cert or RefId
- */
- const char *itemType = "Cert";
- const char *statStr = "OK";
- if(crtn != CSSM_OK) {
- itemType = "RefId";
- statStr = "Cert";
- }
- if((refId.Data == NULL) || (refId.Length == 0)) {
- printf("CSSM_TP_SubmitCredRequest returned %s but no data\n", statStr);
- break;
- }
- if(crtn == CSSM_OK) {
- printf("...cert acquisition complete\n");
- }
- else {
- printf("...Cert request QUEUED\n");
- }
- if(outFile) {
- if(!writeFile(outFile, refId.Data, refId.Length)) {
- if(!quiet) {
- printf("...%lu bytes of %s written to %s\n",
- refId.Length, itemType, outFile);
- }
- }
- else {
- printf("***Error writing %s to %s\n", itemType, outFile);
- crtn = ioErr;
- }
- }
- else if(verbose) {
- if(crtn == CSSM_OK) {
- unsigned char *der;
- unsigned derLen;
- if(pemDecode(refId.Data, refId.Length, &der, &derLen)) {
- printf("***Error PEM decoding returned cert\n");
- }
- else {
- printCert(der, derLen, CSSM_FALSE);
- free(der);
- }
- }
- else {
- printf("RefId data:\n");
- snDumpText(refId.Data, refId.Length);
- }
- }
- break;
- }
- case CSSMERR_APPLE_DOTMAC_REQ_REDIRECT:
- if((refId.Data == NULL) || (refId.Length == 0)) {
- printf("CSSM_TP_SubmitCredRequest returned REDIRECT but no data\n");
- break;
- }
- printf("...cert acquisition : REDIRECTED to: ");
- snDumpText(refId.Data, refId.Length);
- printf("\n");
- break;
- default:
- cssmPerror("CSSM_TP_SubmitCredRequest", crtn);
- break;
- }
- if(csrOutName) {
- if((certReq.csr.Data == NULL) || (certReq.csr.Length == 0)) {
- printf("***Asked for CSR but didn't get one\n");
- ortn = paramErr;
- goto done;
- }
- if(writeFile(csrOutName, certReq.csr.Data, certReq.csr.Length)) {
- printf("***Error writing CSR to %s.\n", csrOutName);
- }
- else {
- printf("...%lu bytes written as CSR to %s\n", certReq.csr.Length, csrOutName);
- }
- }
-done:
- /* cleanup */
- CSSM_ModuleDetach(tpHand);
- if(certReq.clHand) {
- CSSM_ModuleDetach(certReq.clHand);
- }
- if(kcRef) {
- CFRelease(kcRef);
- }
- if(csrInName) {
- free(certReq.csr.Data);
- }
- if(privKeyRef) {
- CFRelease(privKeyRef);
- }
- if(pubKeyRef) {
- CFRelease(pubKeyRef);
- }
- if(refId.Data) {
- cuAppFree(refId.Data, NULL);
- }
- if(doPause) {
- fpurge(stdin);
- printf("Pausing for MallocDebug measurement; CR to continue: ");
- getchar();
- }
-
- return ortn;
-}