1/* Copyright (c) 1998,2005-2006 Apple Computer, Inc. 2 * 3 * makeCertPolicy.cpp - create a self signed cert with a Cert Policies extension 4 */ 5 6#include <utilLib/common.h> 7#include <utilLib/cspwrap.h> 8#include <security_cdsa_utils/cuFileIo.h> 9#include <clAppUtils/CertBuilderApp.h> 10#include <clAppUtils/clutils.h> 11#include <stdlib.h> 12#include <stdio.h> 13#include <string.h> 14#include <Security/cssm.h> 15#include <Security/x509defs.h> 16#include <Security/oidsattr.h> 17#include <Security/oidscert.h> 18#include <Security/oidsalg.h> 19#include <Security/certextensions.h> 20#include <Security/cssmapple.h> 21#include <string.h> 22 23#define ROOT_KEY_LABEL "rootKey" 24/* default key and signature algorithm */ 25#define SIG_ALG_DEFAULT CSSM_ALGID_SHA1WithRSA 26#define KEY_ALG_DEFAULT CSSM_ALGID_RSA 27 28#define CPS_URI "http://www.foo.com" 29 30static void usage(char **argv) 31{ 32 printf("Usage: %s outFileName\n", argv[0]); 33 exit(1); 34} 35 36/* 37 * RDN components for root, subject 38 */ 39CB_NameOid rootRdn[] = 40{ 41 { "Apple Computer DEBUG", &CSSMOID_OrganizationName }, 42 { "Cert Policy Demo", &CSSMOID_CommonName } 43}; 44#define NUM_ROOT_NAMES (sizeof(rootRdn) / sizeof(CB_NameOid)) 45 46int main(int argc, char **argv) 47{ 48 CSSM_CL_HANDLE clHand; // CL handle 49 CSSM_X509_NAME *rootName; 50 CSSM_X509_TIME *notBefore; // UTC-style "not before" time 51 CSSM_X509_TIME *notAfter; // UTC-style "not after" time 52 CSSM_DATA_PTR rawCert; // from CSSM_CL_CertCreateTemplate 53 CSSM_DATA signedRootCert; // from CSSM_CL_CertSign 54 CSSM_CSP_HANDLE cspHand; // CSP handle 55 CSSM_KEY rootPubKey; // root's RSA public key blob 56 CSSM_KEY rootPrivKey; // root's RSA private key - ref format 57 CSSM_RETURN crtn; 58 CSSM_CC_HANDLE signContext; // for signing/verifying the cert 59 60 /* user-spec'd variables */ 61 const char *outFileName; 62 63 if(argc != 2) { 64 usage(argv); 65 } 66 outFileName = argv[1]; 67 68 /* 69 * One extensions. 70 */ 71 CSSM_X509_EXTENSION ext; 72 CE_CertPolicies cp; 73 CE_PolicyInformation cpi; 74 CE_PolicyQualifierInfo cpqi; 75 76 /* connect to CL and CSP */ 77 clHand = clStartup(); 78 if(clHand == 0) { 79 return 0; 80 } 81 cspHand = cspStartup(); 82 if(cspHand == 0) { 83 return 0; 84 } 85 86 /* subsequent errors to abort: to detach */ 87 88 /* cook up an RSA key pair */ 89 crtn = cspGenKeyPair(cspHand, 90 KEY_ALG_DEFAULT, 91 ROOT_KEY_LABEL, 92 strlen(ROOT_KEY_LABEL), 93 512, 94 &rootPubKey, 95 CSSM_FALSE, // pubIsRef - should work both ways, but not yet 96 CSSM_KEYUSE_VERIFY, 97 CSSM_KEYBLOB_RAW_FORMAT_NONE, 98 &rootPrivKey, 99 CSSM_FALSE, // privIsRef 100 CSSM_KEYUSE_SIGN, 101 CSSM_KEYBLOB_RAW_FORMAT_NONE, 102 CSSM_FALSE); 103 if(crtn) { 104 printf("Error creatingt key pair, aborting.\n"); 105 exit(1); 106 } 107 108 /* 109 * Cook up various cert fields. 110 * First, the RDNs for subject and issuer. 111 */ 112 rootName = CB_BuildX509Name(rootRdn, NUM_ROOT_NAMES); 113 if(rootName == NULL) { 114 printf("CB_BuildX509Name failure"); 115 exit(1); 116 } 117 118 /* not before/after in generalized time format */ 119 notBefore = CB_BuildX509Time(0); 120 notAfter = CB_BuildX509Time(10000); 121 122 /* Here's what we do */ 123 ext.extnId = CSSMOID_CertificatePolicies; 124 ext.critical = CSSM_FALSE; 125 ext.format = CSSM_X509_DATAFORMAT_PARSED; 126 127 cpqi.policyQualifierId = CSSMOID_QT_CPS; 128 cpqi.qualifier.Data = (uint8 *)CPS_URI; 129 cpqi.qualifier.Length = strlen(CPS_URI); 130 131 cpi.certPolicyId = CSSMOID_APPLE_CERT_POLICY; /* what I'm testing today */ 132 cpi.numPolicyQualifiers = 1; 133 cpi.policyQualifiers = &cpqi; 134 135 cp.numPolicies = 1; 136 cp.policies = &cpi; 137 138 ext.value.parsedValue = &cp; 139 ext.BERvalue.Data = NULL; 140 ext.BERvalue.Length = 0; 141 142 /* cook up root cert */ 143 printf("Creating root cert...\n"); 144 rawCert = CB_MakeCertTemplate(clHand, 145 0x12345678, // serial number 146 rootName, 147 rootName, 148 notBefore, 149 notAfter, 150 &rootPubKey, 151 SIG_ALG_DEFAULT, 152 NULL, // subjUniqueId 153 NULL, // issuerUniqueId 154 &ext, // extensions 155 1); // numExtensions 156 157 if(rawCert == NULL) { 158 printf("CB_MakeCertTemplate failure"); 159 exit(1); 160 } 161 /* Self-sign */ 162 crtn = CSSM_CSP_CreateSignatureContext(cspHand, 163 SIG_ALG_DEFAULT, 164 NULL, // AccessCred 165 &rootPrivKey, 166 &signContext); 167 if(crtn) { 168 printError("CSSM_CSP_CreateSignatureContext", crtn); 169 exit(1); 170 } 171 signedRootCert.Data = NULL; 172 signedRootCert.Length = 0; 173 crtn = CSSM_CL_CertSign(clHand, 174 signContext, 175 rawCert, // CertToBeSigned 176 NULL, // SignScope 177 0, // ScopeSize, 178 &signedRootCert); 179 if(crtn) { 180 printError("CSSM_CL_CertSign", crtn); 181 exit(1); 182 } 183 crtn = CSSM_DeleteContext(signContext); 184 if(crtn) { 185 printError("CSSM_DeleteContext", crtn); 186 exit(1); 187 } 188 appFreeCssmData(rawCert, CSSM_TRUE); 189 writeFile(outFileName, signedRootCert.Data, signedRootCert.Length); 190 printf("...wrote %lu bytes to %s\n", signedRootCert.Length, outFileName); 191 192 /* Free the stuff we allocd to get here */ 193 CB_FreeX509Name(rootName); 194 CB_FreeX509Time(notBefore); 195 CB_FreeX509Time(notAfter); 196 appFreeCssmData(&signedRootCert, CSSM_FALSE); 197 198 cspFreeKey(cspHand, &rootPubKey); 199 cspFreeKey(cspHand, &rootPrivKey); 200 return 0; 201} 202 203