1// 2// throw C++-dependent stuff in here 3// 4#include <stdio.h> 5#include <Security/cssm.h> 6#include "common.h" 7#include <Security/SecBasePriv.h> 8#include <security_cdsa_client/keychainacl.h> 9#include <security_cdsa_utilities/cssmacl.h> 10#include <security_cdsa_client/aclclient.h> 11#include <security_cdsa_utilities/cssmdata.h> 12#include <security_cdsa_utilities/cssmalloc.h> 13#include <security_utilities/devrandom.h> 14#include <CoreFoundation/CFString.h> 15#include "cssmErrorStrings.h" /* generated error string table */ 16 17/* 18 * Log CSSM error. 19 */ 20void printError(const char *op, CSSM_RETURN err) 21{ 22 cssmPerror(op, err); 23} 24 25const char *cssmErrToStr(CSSM_RETURN err) 26{ 27 const ErrString *esp; 28 29 for(esp=errStrings; esp->errStr!=NULL; esp++) { 30 if(esp->errCode == err) { 31 return esp->errStr; 32 } 33 } 34 35 static char outbuf[512]; 36 sprintf(outbuf, "UNKNOWN ERROR CODE %d", (int)err); 37 return outbuf; 38} 39 40 41/* 42 * Open a DB, optionally: 43 * 44 * -- ensuring it's empty 45 * -- creating it 46 * -- Specifying optional password to avoid SecurityAgent UI. 47 */ 48CSSM_RETURN dbCreateOpen( 49 CSSM_DL_HANDLE dlHand, // from dlStartup() 50 const char *dbName, 51 CSSM_BOOL doCreate, // if false, must already exist 52 CSSM_BOOL deleteExist, 53 const char *pwd, // optional 54 CSSM_DB_HANDLE *dbHand) 55{ 56 CSSM_RETURN crtn; 57 CSSM_DBINFO dbInfo; 58 59 if(deleteExist) { 60 /* first delete possible existing DB, ignore error */ 61 crtn = dbDelete(dlHand, dbName); 62 switch(crtn) { 63 /* only allowed error is "no such file" */ 64 case CSSM_OK: 65 case CSSMERR_DL_DATASTORE_DOESNOT_EXIST: 66 break; 67 default: 68 printError("CSSM_DL_DbDelete", crtn); 69 return crtn; 70 } 71 if(!doCreate) { 72 printf("***Hey! dbCreateOpen with deleteExist and !doCreate\n"); 73 exit(1); 74 } 75 } 76 else { 77 /* 78 * Try to open existing DB. This does not have a means 79 * to specify password (yet). 80 */ 81 crtn = CSSM_DL_DbOpen(dlHand, 82 dbName, 83 NULL, // DbLocation 84 CSSM_DB_ACCESS_READ | CSSM_DB_ACCESS_WRITE, 85 NULL, // CSSM_ACCESS_CREDENTIALS *AccessCred 86 NULL, // void *OpenParameters 87 dbHand); 88 if(crtn == CSSM_OK) { 89 return crtn; 90 } 91 if(!doCreate) { 92 printError("CSSM_DL_DbOpen", crtn); 93 printf("Error opening %s\n", dbName); 94 return crtn; 95 } 96 } 97 memset(&dbInfo, 0, sizeof(CSSM_DBINFO)); 98 99 /* now create it */ 100 if(pwd) { 101 /* 102 * This glorious code copied from crlRefresh. I didn't pretend 103 * to understand it when I put it there either. 104 */ 105 Allocator &alloc = Allocator::standard(); 106 CssmClient::AclFactory::PasswordChangeCredentials 107 pCreds((StringData(pwd)), alloc); 108 const AccessCredentials* aa = pCreds; 109 TypedList subject(alloc, CSSM_ACL_SUBJECT_TYPE_ANY); 110 AclEntryPrototype protoType(subject); 111 AuthorizationGroup &authGroup = protoType.authorization(); 112 CSSM_ACL_AUTHORIZATION_TAG tag = CSSM_ACL_AUTHORIZATION_ANY; 113 authGroup.NumberOfAuthTags = 1; 114 authGroup.AuthTags = &tag; 115 116 const ResourceControlContext rcc(protoType, 117 const_cast<AccessCredentials *>(aa)); 118 119 crtn = CSSM_DL_DbCreate(dlHand, 120 dbName, 121 NULL, // DbLocation 122 &dbInfo, 123 // &Security::KeychainCore::Schema::DBInfo, 124 CSSM_DB_ACCESS_PRIVILEGED, 125 &rcc, // CredAndAclEntry 126 NULL, // OpenParameters 127 dbHand); 128 } 129 else { 130 crtn = CSSM_DL_DbCreate(dlHand, 131 dbName, 132 NULL, // DbLocation 133 &dbInfo, 134 // &Security::KeychainCore::Schema::DBInfo, 135 CSSM_DB_ACCESS_PRIVILEGED, 136 NULL, // CredAndAclEntry 137 NULL, // OpenParameters 138 dbHand); 139 } 140 if(crtn) { 141 printError("CSSM_DL_DbCreate", crtn); 142 } 143 return crtn; 144} 145 146/* 147 * *The* way for all tests to get random data. 148 */ 149void appGetRandomBytes(void *buf, unsigned len) 150{ 151 try { 152 Security::DevRandomGenerator devRand(false); 153 devRand.random(buf, len); 154 } 155 catch(...) { 156 printf("***Hey! DevRandomGenerator threw an exception!\n"); 157 /* Yes, exit - I'd really like to catch one of these */ 158 exit(1); 159 } 160} 161