2 * Copyright (c) 2006 Apple Computer, Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
25 * ExtendedAttribute.cpp - Extended Keychain Item Attribute class.
27 * Created 9/6/06 by dmitch.
30 #include "ExtendedAttribute.h"
31 #include "SecKeychainItemExtendedAttributes.h"
32 #include "SecKeychainItemPriv.h"
33 #include "cssmdatetime.h"
34 #include <security_cdsa_utilities/Schema.h>
36 using namespace KeychainCore
;
39 * Construct new ExtendedAttr from API.
41 ExtendedAttribute::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
),
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
)
57 // db item contstructor
58 ExtendedAttribute::ExtendedAttribute(
59 const Keychain
&keychain
,
60 const PrimaryKey
&primaryKey
,
61 const CssmClient::DbUniqueRecord
&uniqueId
) :
62 ItemImpl(keychain
, primaryKey
, uniqueId
),
64 mItemID(Allocator::standard()),
65 mAttrName(Allocator::standard()),
66 mAttrValue(Allocator::standard())
71 // PrimaryKey item contstructor
72 ExtendedAttribute::ExtendedAttribute(
73 const Keychain
&keychain
,
74 const PrimaryKey
&primaryKey
) :
75 ItemImpl(keychain
, primaryKey
),
77 mItemID(Allocator::standard()),
78 mAttrName(Allocator::standard()),
79 mAttrValue(Allocator::standard())
84 ExtendedAttribute
* ExtendedAttribute::make(const Keychain
&keychain
, const PrimaryKey
&primaryKey
, const CssmClient::DbUniqueRecord
&uniqueId
)
86 ExtendedAttribute
* ea
= new ExtendedAttribute(keychain
, primaryKey
, uniqueId
);
87 keychain
->addItem(primaryKey
, ea
);
93 ExtendedAttribute
* ExtendedAttribute::make(const Keychain
&keychain
, const PrimaryKey
&primaryKey
)
95 ExtendedAttribute
* ea
= new ExtendedAttribute(keychain
, primaryKey
);
96 keychain
->addItem(primaryKey
, ea
);
102 // copy - required due to Item's weird constructor/vendor
103 ExtendedAttribute::ExtendedAttribute(
104 ExtendedAttribute
&extendedAttr
) :
105 ItemImpl(extendedAttr
),
106 mRecordType(extendedAttr
.mRecordType
),
107 mItemID(Allocator::standard()),
108 mAttrName(Allocator::standard()),
109 mAttrValue(Allocator::standard())
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
);
120 ExtendedAttribute::~ExtendedAttribute() throw()
126 ExtendedAttribute::add(Keychain
&keychain
)
128 StLock
<Mutex
>_(mMutex
);
129 // If we already have a Keychain we can't be added.
131 MacOSError::throwMe(errSecDuplicateItem
);
134 CSSMDateTimeUtils::GetCurrentMacLongDateTime(date
);
135 CssmDbAttributeInfo
attrInfo(kSecModDateItemAttr
, CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE
);
136 setAttribute(attrInfo
, date
);
138 Db
db(keychain
->database());
139 // add the item to the (regular) db
142 mUniqueId
= db
->insert(CSSM_DL_DB_RECORD_EXTENDED_ATTRIBUTE
, mDbAttributes
.get(), mData
.get());
144 catch (const CssmError
&e
)
146 if (e
.osStatus() != CSSMERR_DL_INVALID_RECORDTYPE
)
150 * First exposure of this keychain to the extended attribute record type.
151 * Create the relation and try again.
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
);
167 mUniqueId
= db
->insert(CSSM_DL_DB_RECORD_EXTENDED_ATTRIBUTE
, mDbAttributes
.get(), mData
.get());
170 mPrimaryKey
= keychain
->makePrimaryKey(CSSM_DL_DB_RECORD_EXTENDED_ATTRIBUTE
, mUniqueId
);
171 mKeychain
= keychain
;
176 /* set up DB attrs based on member vars */
177 void ExtendedAttribute::setupAttrs()
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
);
186 CssmDbAttributeInfo
attrInfo3(kExtendedAttrAttributeNameAttr
, CSSM_DB_ATTRIBUTE_FORMAT_BLOB
);
187 setAttribute(attrInfo3
, cd
);
189 CssmDbAttributeInfo
attrInfo4(kExtendedAttrAttributeValueAttr
, CSSM_DB_ATTRIBUTE_FORMAT_BLOB
);
190 setAttribute(attrInfo4
, cd
);