#include <Security/Security.h>
#include <Security/SecKeychainItemPriv.h>
#include <unistd.h>
#include <security_cdsa_utils/cuPrintCert.h>
#include "asnUtils.h"
static void usage(char **argv)
{
printf("Usage: %s [emailaddrs] [option...]\n", argv[0]);
printf("Options:\n");
printf(" -p -- print cert contents\n");
printf(" -a -- show all certs, no email match\n");
printf(" -A -- add to default keychain\n");
exit(1);
}
int main(int argc, char **argv)
{
if(argc < 2) {
usage(argv);
}
bool print_cert = false;
bool allCerts = false;
const char *emailAddress = NULL;
bool addToKC = false;
extern int optind;
optind = 1;
if(argv[1][0] != '-') {
emailAddress = argv[1];
optind++;
}
extern char *optarg;
int arg;
while ((arg = getopt(argc, argv, "aphA")) != -1) {
switch (arg) {
case 'p':
print_cert = true;
break;
case 'a':
allCerts = true;
break;
case 'A':
addToKC = true;
break;
case 'h':
default:
usage(argv);
}
}
if(optind != argc) {
usage(argv);
}
if(!allCerts && (emailAddress == NULL)) {
printf("***You must specify either an email address or the -a option.\n");
exit(1);
}
OSStatus ortn;
SecKeychainSearchRef srch;
SecKeychainAttributeList attrList;
SecKeychainAttribute attr;
unsigned numCerts = 0;
if(emailAddress) {
attr.tag = kSecAlias; attr.length = strlen(emailAddress);
attr.data = (void *)emailAddress;
attrList.count = 1;
attrList.attr = &attr;
}
else {
attrList.count = 0;
attrList.attr = NULL;
}
ortn = SecKeychainSearchCreateFromAttributes(NULL, kSecCertificateItemClass,
&attrList,
&srch);
if(ortn) {
cssmPerror("SecKeychainSearchCreateFromAttributes", ortn);
exit(1);
}
do {
SecCertificateRef certRef = NULL;
CSSM_DATA certData;
ortn = SecKeychainSearchCopyNext(srch, (SecKeychainItemRef *)&certRef);
if(ortn) {
break;
}
ortn = SecCertificateGetData(certRef, &certData);
if(ortn) {
cssmPerror("SecCertificateGetData", ortn);
continue;
}
printf("=== Cert %u ===\n", numCerts);
printCertName(certData.Data, certData.Length, NameBoth);
if(print_cert) {
printCert(certData.Data, certData.Length, CSSM_FALSE);
}
if(addToKC) {
SecCertificateRef newCertRef = NULL;
ortn = SecCertificateCreateFromData(&certData,
CSSM_CERT_X_509v3, CSSM_CERT_ENCODING_DER,
&newCertRef);
if(ortn) {
cssmPerror("SecCertificateCreateFromData", ortn);
printf("***Error adding this cert to default keychain.\n");
}
else {
ortn = SecCertificateAddToKeychain(newCertRef, NULL);
if(ortn) {
cssmPerror("SecCertificateAddToKeychain", ortn);
printf("***Error adding this cert to default keychain.\n");
}
else {
printf("...cert added to default keychain.\n");
}
CFRelease(newCertRef);
}
}
CFRelease(certRef);
numCerts++;
} while(ortn == noErr);
printf("...%u certs found matching email address \'%s\'\n", numCerts,
emailAddress ? emailAddress : "<any>");
CFRelease(srch);
return 0;
}