X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/b04fe171f0375ecd5d8a24747ca1dff85720a0ca..6b200bc335dc93c5516ccb52f14bd896d8c7fad7:/SecurityTests/clxutils/dotMacArchive/dotMacArchive.cpp diff --git a/SecurityTests/clxutils/dotMacArchive/dotMacArchive.cpp b/SecurityTests/clxutils/dotMacArchive/dotMacArchive.cpp deleted file mode 100644 index 2b46fd4e..00000000 --- a/SecurityTests/clxutils/dotMacArchive/dotMacArchive.cpp +++ /dev/null @@ -1,546 +0,0 @@ -/* - * dotMacArchive.cpp - test and demonstrate use of dotmacp_tp.bundle to - * manipulate Identity archives ont he .mac server. - */ -#include -#include -#include -//#include -#include -#include "identSearch.h" -#include "dotMacTpAttach.h" -#include -#include -#include -#include - -/* - * Defaults for the test setup du jour - */ -#define USER_DEFAULT "dmitch_new" -#define PWD_DEFAULT "password" -#define ARCHIVE_NAME_DEFAULT "dmitch_new" -#define HOST_DEFAULT "certmgmt.mac.com" - -/* - * Type of archive op - */ -typedef enum { - AO_List, - AO_Store, - AO_Fetch, - AO_Remove -} ArchiveOp; - -static void usage(char **argv) -{ - printf("usage: %s op [options]\n", argv[0]); - printf("Op:\n"); - printf(" l -- list archive contents\n"); - printf(" s -- store archive\n"); - printf(" f -- fetch archive\n"); - printf(" r -- remove archive(s)\n"); - printf("Options:\n"); - printf(" -u username -- Default is %s\n", USER_DEFAULT); - printf(" -Z password -- default is %s\n", PWD_DEFAULT); - printf(" -n archiveName -- default is %s\n", ARCHIVE_NAME_DEFAULT); - printf(" -k keychain -- Source/destination of archive\n"); - printf(" -H hostname -- Alternate .mac server host name (default %s)\n", - HOST_DEFAULT); - printf(" -o outFile -- write P12 blob to outFile\n"); - printf(" -z p12Phrase -- PKCS12 passphrase (default is GUI prompt)\n"); - printf(" -M -- Pause for MallocDebug\n"); - printf(" -l -- loop\n"); - exit(1); -} - -/* print a string in the form of a CSSM_DATA */ -static void printString( - const CSSM_DATA *str) -{ - for(unsigned dex=0; dexLength; dex++) { - printf("%c", str->Data[dex]); - } -} - - -/* - * Post a .mac archive request, with a small number of options. - */ -static CSSM_RETURN dotMacPostArchiveRequest( - ArchiveOp op, - CSSM_TP_HANDLE tpHand, - /* required fields for all ops */ - const CSSM_DATA *userName, // REQUIRED, C string - const CSSM_DATA *password, // REQUIRED, C string - - /* optional (per op, that is...) fields */ - const CSSM_DATA *hostName, // optional alternate host - const CSSM_DATA *archiveName, // required for store, fetch, remove - const CSSM_DATA *timeString, // required for store - const CSSM_DATA *pfxIn, // required for store - CSSM_DATA *pfxOut, // required and RETURNED for fetch - unsigned *numArchives, // required and RETURNED for list - DotMacArchive **archives) // required and RETURNED for list -{ - CSSM_RETURN crtn; - CSSM_TP_AUTHORITY_ID tpAuthority; - CSSM_TP_AUTHORITY_ID *tpAuthPtr = NULL; - CSSM_NET_ADDRESS tpNetAddrs; - CSSM_APPLE_DOTMAC_TP_ARCHIVE_REQUEST archReq; - CSSM_TP_REQUEST_SET reqSet; - CSSM_TP_CALLERAUTH_CONTEXT callerAuth; - sint32 estTime; - CSSM_DATA refId = {0, NULL}; - CSSM_FIELD policyField; - const CSSM_OID *opOid = NULL; - - if((tpHand == 0) || (userName == NULL) || (password == NULL)) { - printf("dotMacPostArchiveRequest: illegal common args\n"); - return paramErr; - } - switch(op) { - case AO_List: - if((numArchives == NULL) || (archives == NULL)) { - printf("dotMacPostArchiveRequest: illegal AO_List args\n"); - return paramErr; - } - opOid = &CSSMOID_DOTMAC_CERT_REQ_ARCHIVE_LIST; - break; - case AO_Store: - if((archiveName == NULL) || (timeString == NULL) || (pfxIn == NULL)) { - printf("dotMacPostArchiveRequest: illegal AO_Store args\n"); - return paramErr; - } - opOid = &CSSMOID_DOTMAC_CERT_REQ_ARCHIVE_STORE; - break; - case AO_Fetch: - if((archiveName == NULL) || (pfxOut == NULL)) { - printf("dotMacPostArchiveRequest: illegal AO_Fetch args\n"); - return paramErr; - } - opOid = &CSSMOID_DOTMAC_CERT_REQ_ARCHIVE_FETCH; - break; - case AO_Remove: - if(archiveName == NULL) { - printf("dotMacPostArchiveRequest: illegal AO_Remove args\n"); - return paramErr; - } - opOid = &CSSMOID_DOTMAC_CERT_REQ_ARCHIVE_REMOVE; - break; - } - - /* - * The main job here is bundling up the arguments into a - * CSSM_APPLE_DOTMAC_TP_ARCHIVE_REQUEST - */ - memset(&archReq, 0, sizeof(archReq)); - archReq.version = CSSM_DOT_MAC_TP_ARCHIVE_REQ_VERSION; - archReq.userName = *userName; - archReq.password = *password; - if(archiveName) { - archReq.archiveName = *archiveName; - } - if(timeString) { - archReq.timeString = *timeString; - } - if(pfxIn) { - archReq.pfx = *pfxIn; - } - - /* remaining arguments for TP call... */ - if((hostName != NULL) && (hostName->Data != NULL)) { - tpAuthority.AuthorityCert = NULL; - tpAuthority.AuthorityLocation = &tpNetAddrs; - tpNetAddrs.AddressType = CSSM_ADDR_NAME; - tpNetAddrs.Address = *hostName; - tpAuthPtr = &tpAuthority; - } - - reqSet.NumberOfRequests = 1; - reqSet.Requests = &archReq; - - policyField.FieldOid = *opOid; - policyField.FieldValue.Data = NULL; - policyField.FieldValue.Length = 0; - memset(&callerAuth, 0, sizeof(callerAuth)); - callerAuth.Policy.NumberOfPolicyIds = 1; - callerAuth.Policy.PolicyIds = &policyField; - - 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 - if(crtn) { - cssmPerror("CSSM_TP_SubmitCredRequest", crtn); - } - - /* success: post-process */ - switch(op) { - case AO_List: - *numArchives = archReq.numArchives; - *archives = archReq.archives; - break; - case AO_Store: - break; - case AO_Fetch: - *pfxOut = archReq.pfx; - break; - case AO_Remove: - break; - } - - return CSSM_OK; -} - -static void cStringToCssmData( - const char *cstr, - CSSM_DATA *cdata) -{ - if(cstr) { - cdata->Data = (uint8 *)cstr; - cdata->Length = strlen(cstr); - } - else { - cdata->Data = NULL; - cdata->Length = 0; - } -} - -int main(int argc, char **argv) -{ - SecKeychainRef kcRef = NULL; - CSSM_RETURN crtn; - CSSM_TP_HANDLE tpHand = 0; - OSStatus ortn; - - /* user-spec'd variables */ - ArchiveOp op = AO_List; - char *keychainName = NULL; - const char *userName = USER_DEFAULT; - const char *password = PWD_DEFAULT; - const char *archName = ARCHIVE_NAME_DEFAULT; - const char *hostName = HOST_DEFAULT; - char *outFile = NULL; - bool doPause = false; - bool loop = false; - char *p12Phrase = NULL; - - if(argc < 2) { - usage(argv); - } - switch(argv[1][0]) { - case 'l': - op = AO_List; - break; - case 's': - op = AO_Store; - break; - case 'f': - op = AO_Fetch; - break; - case 'r': - op = AO_Remove; - break; - default: - usage(argv); - } - - extern char *optarg; - extern int optind; - optind = 2; - int arg; - while ((arg = getopt(argc, argv, "u:Z:n:k:H:Nlo:z:")) != -1) { - switch (arg) { - case 'u': - userName = optarg; - break; - case 'Z': - password = optarg; - break; - case 'n': - archName = optarg; - break; - case 'k': - keychainName = optarg; - break; - case 'M': - doPause = true; - break; - case 'H': - hostName = optarg; - break; - case 'l': - loop = true; - break; - case 'o': - outFile = optarg; - break; - case 'z': - p12Phrase = optarg; - break; - case 'h': - usage(argv); - } - } - if(optind != argc) { - usage(argv); - } - - if(doPause) { - fpurge(stdin); - printf("Pausing for MallocDebug attach; CR to continue: "); - getchar(); - } - - 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); - exit(1); - } - } - - /* bundle up our crufty C string args into CSSM_DATAs needed at the TP SPI */ - CSSM_DATA userNameData; - CSSM_DATA passwordData; - CSSM_DATA hostNameData; - CSSM_DATA archNameData; - CSSM_DATA timeStringData; - - cStringToCssmData(userName, &userNameData); - cStringToCssmData(password, &passwordData); - cStringToCssmData(hostName, &hostNameData); - cStringToCssmData(archName, &archNameData); - - /* time in seconds since the epoch, sprintf'd in base 10 */ - char timeStr[20]; - time_t nowTime = time(NULL); - printf("...nowTime = %lu\n", nowTime); - //nowTime += (60 * 60 * 24 * 26); // fails - nowTime += (60 * 60 * 24 * 25); // works - printf("...expirationTime = %lu\n", nowTime); - sprintf(timeStr, "%lu", nowTime); - timeStringData.Data = (uint8 *)timeStr; - timeStringData.Length = strlen(timeStr); - - /* other data needed by dotMacPostArchiveRequest() */ - CFDataRef p12 = NULL; - CSSM_DATA pfxInData = {0, NULL}; - CSSM_DATA pfxOutData = {0, NULL}; - unsigned numArchives = 0; - DotMacArchive *archives = NULL; - - /* Store op: get identity in p12 form */ - if(op == AO_Store) { - CFStringRef cfPhrase = NULL; - - /* Cert attribute - email address - contains the "@mac.com" */ - char emailAddr[500]; - strcpy(emailAddr, userName); - // nope strcat(emailAddr, "@mac.com"); - - /* find an identity for that email address */ - SecIdentityRef idRef = NULL; - OSStatus ortn = findIdentity(emailAddr, strlen(emailAddr), kcRef, &idRef); - if(ortn) { - printf("***Could not find an identity to store. Aborting.\n"); - goto errOut; - } - - /* convert that identity to p12 */ - SecKeyImportExportParameters keyParams; - memset(&keyParams, 0, sizeof(keyParams)); - keyParams.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION; - if(p12Phrase) { - cfPhrase = CFStringCreateWithCString(NULL, p12Phrase, - kCFStringEncodingUTF8); - keyParams.passphrase = cfPhrase; - } - else { - keyParams.flags = kSecKeySecurePassphrase; - } - keyParams.alertTitle = CFSTR(".mac Identity Backup"); - keyParams.alertPrompt = - CFSTR("Enter passphrase for encrypting your .mac private key"); - ortn = SecKeychainItemExport(idRef, kSecFormatPKCS12, kSecItemPemArmour, - &keyParams, &p12); - if(ortn) { - cssmPerror("SecKeychainItemExport", crtn); - printf("***Error obtaining .mac identity in PKCS12 format. Aborting.\n"); - goto errOut; - } - - pfxInData.Data = (uint8 *)CFDataGetBytePtr(p12); - pfxInData.Length = CFDataGetLength(p12); - printf("...preparing to store archive of %lu bytes\n", pfxInData.Length); - - if(outFile) { - if(writeFile(outFile, pfxInData.Data, pfxInData.Length)) { - printf("***Error writing P12 to %s\n", outFile); - } - else { - printf("...wrote %lu bytes to %s\n", pfxInData.Length, outFile); - } - } - if(cfPhrase) { - CFRelease(cfPhrase); - } - } - - /* attach to the TP */ - tpHand = dotMacTpAttach(); - if(tpHand == 0) { - printf("***Error attaching to .mac TP; aborting.\n"); - ortn = -1; - goto errOut; - } - - /* go */ - crtn = dotMacPostArchiveRequest(op, tpHand, &userNameData, &passwordData, - hostName ? &hostNameData : NULL, - &archNameData, - &timeStringData, - &pfxInData, - &pfxOutData, - &numArchives, - &archives); - if(crtn) { - printf("***Error performing archive request; aborting.\n"); - goto errOut; - } - - /* post-request processing */ - - switch(op) { - case AO_List: - { - printf("=== List request complete; numArchives = %u ===\n", numArchives); - for(unsigned dex=0; dexarchiveName); - printf("\n"); - - printf(" time : "); - printString(&dmarch->timeString); - printf("\n"); - - /* now free what the TP allocated on our behalf */ - APP_FREE(dmarch->archiveName.Data); - APP_FREE(dmarch->timeString.Data); - } - APP_FREE(archives); - break; - } - - case AO_Store: - printf("=== archive \'%s\' backup complete ===\n", archName); - break; - case AO_Fetch: - { - bool didSomething = false; - if(pfxOutData.Length == 0) { - printf("***Archive fetch claimed to succeed, but no data seen\n"); - ortn = -1; - goto errOut; - } - - /* - * OK, we have a blob of PKCS12 data. Import to keychain and/or write it - * to a file. - */ - printf("=== %lu bytes of archive fetched ===\n", pfxOutData.Length); - if(outFile) { - if(writeFile(outFile, pfxOutData.Data, pfxOutData.Length)) { - printf("***Error writing P12 to %s\n", outFile); - } - else { - printf("...wrote %lu bytes to %s\n", pfxOutData.Length, outFile); - didSomething = true; - } - } - if(kcRef) { - /* Note we avoid importing to default keychain - user must really want - * to perform this step */ - CFDataRef p12Data = CFDataCreate(NULL, pfxOutData.Data, pfxOutData.Length); - SecExternalFormat extForm = kSecFormatPKCS12; - SecKeyImportExportParameters keyParams; - memset(&keyParams, 0, sizeof(keyParams)); - keyParams.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION; - CFStringRef cfPhrase = NULL; - if(p12Phrase) { - cfPhrase = CFStringCreateWithCString(NULL, p12Phrase, - kCFStringEncodingUTF8); - keyParams.passphrase = cfPhrase; - } - else { - keyParams.flags = kSecKeySecurePassphrase; - } - keyParams.alertTitle = CFSTR(".mac Identity Restore"); - keyParams.alertPrompt = - CFSTR("Enter passphrase for decrypting your .mac private key"); - - /* go... */ - ortn = SecKeychainItemImport(p12Data, - NULL, // filename - passing kSecFormatPKCS12 is definitely enough - &extForm, - NULL, // itemType - import'll figure it out - 0, // SecItemImportExportFlags - &keyParams, - kcRef, - NULL); // we don't want any items returned - if(ortn) { - cssmPerror("SecKeychainItemImport", ortn); - printf("***Error importing p12 into keychain %s\n", keychainName); - } - else { - printf("...archive successfully imported into keychain %s\n", - keychainName); - didSomething = true; - } - if(cfPhrase) { - CFRelease(cfPhrase); - } - } - if(!didSomething) { - printf("...note we got an archive from the server but didn't have a " - "place to put it.\n"); - } - break; - } - case AO_Remove: - printf("=== Archive %s removed ===\n", archName); - break; - } - - if(doPause) { - fpurge(stdin); - printf("Pausing at end of test for MallocDebug attach; CR to continue: "); - getchar(); - } - -errOut: - if(kcRef) { - CFRelease(kcRef); - } - - if(tpHand) { - dotMacTpDetach(tpHand); - } - return ortn; -} -