X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/b04fe171f0375ecd5d8a24747ca1dff85720a0ca..6b200bc335dc93c5516ccb52f14bd896d8c7fad7:/SecurityTests/clxutils/dotMacRequest/dotMacRequest.cpp diff --git a/SecurityTests/clxutils/dotMacRequest/dotMacRequest.cpp b/SecurityTests/clxutils/dotMacRequest/dotMacRequest.cpp deleted file mode 100644 index e610eed4..00000000 --- a/SecurityTests/clxutils/dotMacRequest/dotMacRequest.cpp +++ /dev/null @@ -1,624 +0,0 @@ -/* - * dotMacRequest.cpp - simple illustration of using SecCertificateRequestCreate() and - * SecCertificateRequestSubmit to post a request for a .mac cert. - */ -#include -#include -#include -#include -#include -#include - -/* - * Defaults for the test setup du jour - */ -#define USER_DEFAULT "dmitch10" -#define PWD_DEFAULT "password" -#define HOST_DEFAULT "certmgmt.mac.com" - -/* - * Type of cert to request - */ -typedef enum { - CRT_Identity, /* actually, now "iChat encryption", not "identity" */ - CRT_EmailSign, - CRT_EmailEncrypt -} CertRequestType; - -static void usage(char **argv) -{ - printf("usage: %s op [options]\n", argv[0]); - printf("Op:\n"); - printf(" i -- generate iChat encryption cert\n"); - printf(" s -- generate email signing cert\n"); - printf(" e -- generate email encrypting cert\n"); - printf(" I -- search/retrieve request for iChat encryption cert\n"); - printf(" S -- search/retrieve request for signing cert\n"); - printf(" E -- search/retrieve request for encrypting cert\n"); - printf(" p -- pending request poll (via -u)\n"); - printf("Options:\n"); - printf(" -u username -- Default is %s\n", USER_DEFAULT); - printf(" -Z password -- default is %s\n", PWD_DEFAULT); - printf(" -p -- pick key pair from existing (default is generate)\n"); - printf(" -k keychain -- Source/destination of keys\n"); - printf(" -r -- Renew (default is new)\n"); - printf(" -a -- async (default is synchronous)\n"); - printf(" -H hostname -- Alternate .mac server host name (default %s)\n", - HOST_DEFAULT); - printf(" -M -- Pause for MallocDebug\n"); - printf(" -l -- loop\n"); - exit(1); -} - -/* print a string int he form of a CSSM_DATA */ -static void printString( - const CSSM_DATA *str) -{ - for(unsigned dex=0; dexLength; dex++) { - printf("%c", str->Data[dex]); - } -} - -/* basic "generate keypair" routine */ -static OSStatus genKeyPair( - SecKeychainRef kcRef, // optional, 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; -} - -/* max number of oid/value pairs */ -#define MAX_ATTRS 5 - -/* - * search for a pending .mac cert request, get current status. - */ -static OSStatus dotMacGetPendingRequest( - /* required fields */ - const char *userName, // REQUIRED, C string - const char *password, // REQUIRED, C string - CertRequestType requestType, - - /* optional fields */ - const char *hostName, // C string - SecKeychainRef keychain) // destination of created cert (if !async) -{ - SecCertificateRequestAttribute attrs[MAX_ATTRS]; - SecCertificateRequestAttribute *attrp = attrs; - SecCertificateRequestAttributeList attrList; - - attrList.count = 0; - attrList.attr = attrs; - - /* user name */ - attrp->oid = CSSMOID_DOTMAC_CERT_REQ_VALUE_USERNAME; - attrp->value.Data = (uint8 *)userName; - attrp->value.Length = strlen(userName); - attrp++; - attrList.count++; - - /* password */ - attrp->oid = CSSMOID_DOTMAC_CERT_REQ_VALUE_PASSWORD; - attrp->value.Data = (uint8 *)password; - attrp->value.Length = strlen(password); - attrp++; - attrList.count++; - - /* options */ - - if(hostName) { - attrp->oid = CSSMOID_DOTMAC_CERT_REQ_VALUE_HOSTNAME; - attrp->value.Data = (uint8 *)hostName; - attrp->value.Length = strlen(hostName); - attrp++; - attrList.count++; - } - - /* map CertRequestType to a policy OID */ - const CSSM_OID *policy; - switch(requestType) { - case CRT_Identity: - policy = &CSSMOID_DOTMAC_CERT_REQ_IDENTITY; - break; - case CRT_EmailSign: - policy = &CSSMOID_DOTMAC_CERT_REQ_EMAIL_SIGN; - break; - case CRT_EmailEncrypt: - policy = &CSSMOID_DOTMAC_CERT_REQ_EMAIL_ENCRYPT; - break; - default: - printf("GAK! Bad cert type.\n"); - return -1; - } - OSStatus ortn; - SecCertificateRequestRef certReq = NULL; - SecCertificateRef certRef = NULL; - sint32 estTime; - - printf("...calling SecCertificateFindRequest\n"); - ortn = SecCertificateFindRequest(policy, - CSSM_CERT_X_509v3, - CSSM_TP_AUTHORITY_REQUEST_CERTISSUE, - NULL, NULL, // no keys needed - &attrList, - &certReq); - if(ortn) { - cssmPerror("SecCertificateFindRequest", ortn); - return ortn; - } - - printf("...calling SecCertificateRequestGetResult\n"); - ortn = SecCertificateRequestGetResult(certReq, keychain, &estTime, &certRef); - if(ortn) { - cssmPerror("SecCertificateRequestGetResult", ortn); - } - else { - printf("...SecCertificateRequestGetResult succeeded; estTime %d; cert %s\n", - (int)estTime, certRef ? "OBTAINED" : "NOT OBTAINED"); - } - if(certRef) { - CFRelease(certRef); - } - if(certReq) { - CFRelease(certReq); - } - return ortn; -} - -/* - * Do an "is there a pending request for this user?" poll. - * That function - via SecCertificateFindRequest() always returns an error; - * *we* only return an error if the result is something other than the - * expected two results: - * CSSMERR_APPLE_DOTMAC_REQ_IS_PENDING - * CSSMERR_APPLE_DOTMAC_NO_REQ_PENDING - */ -static OSStatus dotMacPostPendingReqPoll( - const char *userName, - const char *password, - const char *hostName) -{ - SecCertificateRequestAttribute attrs[MAX_ATTRS]; - SecCertificateRequestAttribute *attrp = attrs; - SecCertificateRequestAttributeList attrList; - uint8 oneBit = 1; - - attrList.count = 0; - attrList.attr = attrs; - - /* user name, required */ - attrp->oid = CSSMOID_DOTMAC_CERT_REQ_VALUE_USERNAME; - attrp->value.Data = (uint8 *)userName; - attrp->value.Length = strlen(userName); - attrp++; - attrList.count++; - - /* password, required */ - attrp->oid = CSSMOID_DOTMAC_CERT_REQ_VALUE_PASSWORD; - attrp->value.Data = (uint8 *)password; - attrp->value.Length = strlen(password); - attrp++; - attrList.count++; - - /* the "poll the server" indicator */ - attrp->oid = CSSMOID_DOTMAC_CERT_REQ_VALUE_IS_PENDING; - /* true ::= any nonzero data */ - attrp->value.Data = &oneBit; - attrp->value.Length = 1; - attrp++; - attrList.count++; - - /* options */ - - if(hostName) { - attrp->oid = CSSMOID_DOTMAC_CERT_REQ_VALUE_HOSTNAME; - attrp->value.Data = (uint8 *)hostName; - attrp->value.Length = strlen(hostName); - attrp++; - attrList.count++; - } - - /* policy, not technically needed; use this one by convention */ - const CSSM_OID *policy = &CSSMOID_DOTMAC_CERT_REQ_IDENTITY; - - OSStatus ortn; - SecCertificateRequestRef certReq = NULL; - - printf("...calling SecCertificateFindRequest\n"); - ortn = SecCertificateFindRequest(policy, - CSSM_CERT_X_509v3, - CSSM_TP_AUTHORITY_REQUEST_CERTISSUE, - NULL, NULL, // no keys needed - &attrList, - &certReq); - - switch(ortn) { - case CSSMERR_APPLE_DOTMAC_REQ_IS_PENDING: - printf("...result: REQ_IS_PENDING\n"); - ortn = noErr; - break; - case CSSMERR_APPLE_DOTMAC_NO_REQ_PENDING: - printf("...result: NO_REQ_PENDING\n"); - ortn = noErr; - break; - case noErr: - /* should never happen */ - printf("...UNEXPECTED SUCCESS on SecCertificateFindRequest\n"); - ortn = internalComponentErr; - if(certReq != NULL) { - /* Somehow, it got created */ - CFRelease(certReq); - } - break; - default: - cssmPerror("SecCertificateFindRequest", ortn); - break; - } - return ortn; -} - -/* - * Post a .mac cert request, with a small number of options. - */ -static OSStatus dotMacPostCertRequest( - /* required fields */ - const char *userName, // REQUIRED, C string - const char *password, // REQUIRED, C string - SecKeyRef privKey, // REQUIRED - SecKeyRef pubKey, - CertRequestType requestType, - bool renew, // false: new cert - // true : renew existing - bool async, // false: wait for result - // true : just post request and return - /* optional fields */ - const char *hostName, // C string - SecKeychainRef keychain) // destination of created cert (if !async) -{ - - /* the main job here is bundling up the arguments in an array of OID/value pairs */ - SecCertificateRequestAttribute attrs[MAX_ATTRS]; - SecCertificateRequestAttribute *attrp = attrs; - SecCertificateRequestAttributeList attrList; - uint8 oneBit = 1; - - attrList.count = 0; - attrList.attr = attrs; - - /* user name */ - attrp->oid = CSSMOID_DOTMAC_CERT_REQ_VALUE_USERNAME; - attrp->value.Data = (uint8 *)userName; - attrp->value.Length = strlen(userName); - attrp++; - attrList.count++; - - /* password */ - attrp->oid = CSSMOID_DOTMAC_CERT_REQ_VALUE_PASSWORD; - attrp->value.Data = (uint8 *)password; - attrp->value.Length = strlen(password); - attrp++; - attrList.count++; - - /* options */ - - if(hostName) { - attrp->oid = CSSMOID_DOTMAC_CERT_REQ_VALUE_HOSTNAME; - attrp->value.Data = (uint8 *)hostName; - attrp->value.Length = strlen(hostName); - attrp++; - attrList.count++; - } - - if(renew) { - attrp->oid = CSSMOID_DOTMAC_CERT_REQ_VALUE_RENEW; - /* true ::= any nonzero data */ - attrp->value.Data = &oneBit; - attrp->value.Length = 1; - attrp++; - attrList.count++; - } - - if(async) { - attrp->oid = CSSMOID_DOTMAC_CERT_REQ_VALUE_ASYNC; - /* true ::= any nonzero data */ - attrp->value.Data = &oneBit; - attrp->value.Length = 1; - attrp++; - attrList.count++; - } - - /* map CertRequestType to a policy OID */ - const CSSM_OID *policy; - switch(requestType) { - case CRT_Identity: - policy = &CSSMOID_DOTMAC_CERT_REQ_IDENTITY; - break; - case CRT_EmailSign: - policy = &CSSMOID_DOTMAC_CERT_REQ_EMAIL_SIGN; - break; - case CRT_EmailEncrypt: - policy = &CSSMOID_DOTMAC_CERT_REQ_EMAIL_ENCRYPT; - break; - default: - printf("GAK! Bad cert type.\n"); - return -1; - } - OSStatus ortn; - SecCertificateRequestRef certReq = NULL; - - ortn = SecCertificateRequestCreate(policy, - CSSM_CERT_X_509v3, - CSSM_TP_AUTHORITY_REQUEST_CERTISSUE, - privKey, - pubKey, - &attrList, - &certReq); - if(ortn) { - cssmPerror("SecCertificateRequestCreate", ortn); - return ortn; - } - - printf("...submitting request to .mac server\n"); - sint32 estTime = 0; - ortn = SecCertificateRequestSubmit(certReq, &estTime); - switch(ortn) { - case CSSMERR_APPLE_DOTMAC_REQ_REDIRECT: - { - /* - * A special case; the server is redirecting the calling app to - * a URL which we fetch and report like so: - */ - CSSM_DATA url = {0, NULL}; - ortn = SecCertificateRequestGetData(certReq, &url); - if(ortn) { - cssmPerror("SecCertificateRequestGetData", ortn); - printf("***APPLE_DOTMAC_REQ_REDIRECT obtained but no URL availalble.\n"); - } - else { - printf("***APPLE_DOTMAC_REQ_REDIRECT obtained; redirect URL is: "); - printString(&url); - printf("\n"); - } - break; - } - - case CSSM_OK: - printf("...cert request submitted; estimatedTime %d.\n", (int)estTime); - break; - default: - cssmPerror("SecCertificateRequestSubmit", ortn); - break; - } - if(ortn || async) { - /* we're done */ - CFRelease(certReq); - return ortn; - } - - /* - * Running synchronously, and the submit succeeded. Try to get a result. - * In the real world this would be polled, every so often.... - */ - SecCertificateRef certRef = NULL; - printf("...attempting to get result of cert request...\n"); - ortn = SecCertificateRequestGetResult(certReq, keychain, &estTime, &certRef); - if(ortn) { - cssmPerror("SecCertificateRequestGetResult", ortn); - } - else { - printf("...SecCertificateRequestGetResult succeeded; estTime %d; cert %s\n", - (int)estTime, certRef ? "OBTAINED" : "NOT OBTAINED"); - } - if(certRef) { - CFRelease(certRef); - CFRelease(certReq); - } - return ortn; -} - -#define ALWAYS_DO_SUBMIT 0 - - -int main(int argc, char **argv) -{ - SecKeyRef pubKeyRef = NULL; - SecKeyRef privKeyRef = NULL; - SecKeychainRef kcRef = NULL; - OSStatus ortn; - - /* user-spec'd variables */ - bool genKeys = true; /* true: generate; false: pick 'em */ - char *keychainName = NULL; - char *userName = USER_DEFAULT; - char *password = PWD_DEFAULT; - char *hostName = NULL; /* leave as the default! = HOST_DEFAULT; */ - /* - * WARNING: doing a renew operation requires that you delete your *current* - * .mac cert from the destination keychain. The DB attrs of the old and new certs - * are the same! - */ - bool doRenew = false; - CertRequestType reqType = CRT_Identity; - bool doPause = false; - bool async = false; - bool doSearch = false; /* false: post cert request - * true : search for existing request, get - * status for it */ - bool loop = false; - bool doPendingReqPoll = false; - - if(argc < 2) { - usage(argv); - } - switch(argv[1][0]) { - case 'i': - reqType = CRT_Identity; - break; - case 's': - reqType = CRT_EmailSign; - break; - case 'e': - reqType = CRT_EmailEncrypt; - break; - case 'I': - doSearch = true; - reqType = CRT_Identity; - break; - case 'S': - doSearch = true; - reqType = CRT_EmailSign; - break; - case 'E': - doSearch = true; - reqType = CRT_EmailEncrypt; - break; - case 'p': - doPendingReqPoll = true; - break; - default: - usage(argv); - } - - extern char *optarg; - extern int optind; - optind = 2; - int arg; - while ((arg = getopt(argc, argv, "u:Z:pk:rMH:al")) != -1) { - switch (arg) { - case 'u': - userName = optarg; - break; - case 'Z': - password = optarg; - break; - case 'p': - genKeys = false; - break; - case 'k': - keychainName = optarg; - break; - case 'r': - doRenew = true; - break; - case 'M': - doPause = true; - break; - case 'H': - hostName = optarg; - break; - case 'a': - async = true; - break; - case 'l': - loop = true; - break; - case 'h': - default: - 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); - } - } - - if((!doSearch || ALWAYS_DO_SUBMIT) && !doPendingReqPoll) { - /* 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); - } - } - - /* go */ - do { - if(doSearch) { - #if ALWAYS_DO_SUBMIT - /* debug only */ - dotMacPostCertRequest(userName, password, privKeyRef, pubKeyRef, - reqType, doRenew, async, hostName, kcRef); - #endif - - /* end */ - ortn = dotMacGetPendingRequest(userName, password, reqType, hostName, kcRef); - } - else if(doPendingReqPoll) { - ortn = dotMacPostPendingReqPoll(userName, password, hostName); - } - else { - ortn = dotMacPostCertRequest(userName, password, privKeyRef, pubKeyRef, - reqType, doRenew, async, hostName, kcRef); - } - if(doPause) { - fpurge(stdin); - printf("Pausing for MallocDebug attach; CR to continue: "); - getchar(); - } - } while(loop); - if(privKeyRef) { - CFRelease(privKeyRef); - } - if(pubKeyRef) { - CFRelease(pubKeyRef); - } - if(kcRef) { - CFRelease(kcRef); - } - - if(doPause) { - fpurge(stdin); - printf("Pausing at end of test for MallocDebug attach; CR to continue: "); - getchar(); - } - - return ortn; -} -