1/* 2 * Copyright (c) 2006 Apple Computer, Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24/* 25 * ExtendedAttribute.cpp - Extended Keychain Item Attribute class. 26 * 27 * Created 9/6/06 by dmitch. 28 */ 29 30#include "ExtendedAttribute.h" 31#include "SecKeychainItemExtendedAttributes.h" 32#include "SecKeychainItemPriv.h" 33#include "cssmdatetime.h" 34#include <security_cdsa_utilities/Schema.h> 35 36using namespace KeychainCore; 37 38/* 39 * Construct new ExtendedAttr from API. 40 */ 41ExtendedAttribute::ExtendedAttribute( 42 CSSM_DB_RECORDTYPE recordType, 43 const CssmData &itemID, 44 const CssmData attrName, 45 const CssmData attrValue) : 46 ItemImpl(CSSM_DL_DB_RECORD_EXTENDED_ATTRIBUTE, 47 reinterpret_cast<SecKeychainAttributeList *>(NULL), 48 0, NULL), 49 mRecordType(recordType), 50 mItemID(Allocator::standard(), itemID.Data, itemID.Length), 51 mAttrName(Allocator::standard(), attrName.Data, attrName.Length), 52 mAttrValue(Allocator::standard(), attrValue.Data, attrValue.Length) 53{ 54 setupAttrs(); 55} 56 57// db item contstructor 58ExtendedAttribute::ExtendedAttribute( 59 const Keychain &keychain, 60 const PrimaryKey &primaryKey, 61 const CssmClient::DbUniqueRecord &uniqueId) : 62 ItemImpl(keychain, primaryKey, uniqueId), 63 mRecordType(0), 64 mItemID(Allocator::standard()), 65 mAttrName(Allocator::standard()), 66 mAttrValue(Allocator::standard()) 67{ 68 69} 70 71// PrimaryKey item contstructor 72ExtendedAttribute::ExtendedAttribute( 73 const Keychain &keychain, 74 const PrimaryKey &primaryKey) : 75 ItemImpl(keychain, primaryKey), 76 mRecordType(0), 77 mItemID(Allocator::standard()), 78 mAttrName(Allocator::standard()), 79 mAttrValue(Allocator::standard()) 80{ 81 82} 83 84ExtendedAttribute* ExtendedAttribute::make(const Keychain &keychain, const PrimaryKey &primaryKey, const CssmClient::DbUniqueRecord &uniqueId) 85{ 86 ExtendedAttribute* ea = new ExtendedAttribute(keychain, primaryKey, uniqueId); 87 keychain->addItem(primaryKey, ea); 88 return ea; 89} 90 91 92 93ExtendedAttribute* ExtendedAttribute::make(const Keychain &keychain, const PrimaryKey &primaryKey) 94{ 95 ExtendedAttribute* ea = new ExtendedAttribute(keychain, primaryKey); 96 keychain->addItem(primaryKey, ea); 97 return ea; 98} 99 100 101 102// copy - required due to Item's weird constructor/vendor 103ExtendedAttribute::ExtendedAttribute( 104 ExtendedAttribute &extendedAttr) : 105 ItemImpl(extendedAttr), 106 mRecordType(extendedAttr.mRecordType), 107 mItemID(Allocator::standard()), 108 mAttrName(Allocator::standard()), 109 mAttrValue(Allocator::standard()) 110{ 111 // CssmData cd = extendedAttr.mItemID; 112 mItemID.copy(extendedAttr.mItemID); 113 // cd = extendedAttr.mAttrName; 114 mAttrName.copy(extendedAttr.mAttrName); 115 // cd = extendedAttr.mAttrValue; 116 mAttrValue.copy(extendedAttr.mAttrValue); 117 setupAttrs(); 118} 119 120ExtendedAttribute::~ExtendedAttribute() throw() 121{ 122 123} 124 125PrimaryKey 126ExtendedAttribute::add(Keychain &keychain) 127{ 128 StLock<Mutex>_(mMutex); 129 // If we already have a Keychain we can't be added. 130 if (mKeychain) 131 MacOSError::throwMe(errSecDuplicateItem); 132 133 SInt64 date; 134 CSSMDateTimeUtils::GetCurrentMacLongDateTime(date); 135 CssmDbAttributeInfo attrInfo(kSecModDateItemAttr, CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE); 136 setAttribute(attrInfo, date); 137 138 Db db(keychain->database()); 139 // add the item to the (regular) db 140 try 141 { 142 mUniqueId = db->insert(CSSM_DL_DB_RECORD_EXTENDED_ATTRIBUTE, mDbAttributes.get(), mData.get()); 143 } 144 catch (const CssmError &e) 145 { 146 if (e.osStatus() != CSSMERR_DL_INVALID_RECORDTYPE) 147 throw; 148 149 /* 150 * First exposure of this keychain to the extended attribute record type. 151 * Create the relation and try again. 152 */ 153 db->createRelation(CSSM_DL_DB_RECORD_EXTENDED_ATTRIBUTE, 154 "CSSM_DL_DB_RECORD_EXTENDED_ATTRIBUTE", 155 Schema::ExtendedAttributeSchemaAttributeCount, 156 Schema::ExtendedAttributeSchemaAttributeList, 157 Schema::ExtendedAttributeSchemaIndexCount, 158 Schema::ExtendedAttributeSchemaIndexList); 159 keychain->keychainSchema()->didCreateRelation( 160 CSSM_DL_DB_RECORD_EXTENDED_ATTRIBUTE, 161 "CSSM_DL_DB_RECORD_EXTENDED_ATTRIBUTE", 162 Schema::ExtendedAttributeSchemaAttributeCount, 163 Schema::ExtendedAttributeSchemaAttributeList, 164 Schema::ExtendedAttributeSchemaIndexCount, 165 Schema::ExtendedAttributeSchemaIndexList); 166 167 mUniqueId = db->insert(CSSM_DL_DB_RECORD_EXTENDED_ATTRIBUTE, mDbAttributes.get(), mData.get()); 168 } 169 170 mPrimaryKey = keychain->makePrimaryKey(CSSM_DL_DB_RECORD_EXTENDED_ATTRIBUTE, mUniqueId); 171 mKeychain = keychain; 172 173 return mPrimaryKey; 174} 175 176/* set up DB attrs based on member vars */ 177void ExtendedAttribute::setupAttrs() 178{ 179 StLock<Mutex>_(mMutex); 180 CssmDbAttributeInfo attrInfo1(kExtendedAttrRecordTypeAttr, CSSM_DB_ATTRIBUTE_FORMAT_UINT32); 181 setAttribute(attrInfo1, (uint32)mRecordType); 182 CssmData cd = mItemID; 183 CssmDbAttributeInfo attrInfo2(kExtendedAttrItemIDAttr, CSSM_DB_ATTRIBUTE_FORMAT_BLOB); 184 setAttribute(attrInfo2, cd); 185 cd = mAttrName; 186 CssmDbAttributeInfo attrInfo3(kExtendedAttrAttributeNameAttr, CSSM_DB_ATTRIBUTE_FORMAT_BLOB); 187 setAttribute(attrInfo3, cd); 188 cd = mAttrValue; 189 CssmDbAttributeInfo attrInfo4(kExtendedAttrAttributeValueAttr, CSSM_DB_ATTRIBUTE_FORMAT_BLOB); 190 setAttribute(attrInfo4, cd); 191} 192 193 194