2 * Copyright (c) 2006,2011,2014 Apple 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.
29 #include "ExtendedAttribute.h"
30 #include "SecKeychainItemExtendedAttributes.h"
31 #include "SecKeychainItemPriv.h"
32 #include "cssmdatetime.h"
33 #include <security_cdsa_utilities/Schema.h>
35 using namespace KeychainCore
;
38 * Construct new ExtendedAttr from API.
40 ExtendedAttribute::ExtendedAttribute(
41 CSSM_DB_RECORDTYPE recordType
,
42 const CssmData
&itemID
,
43 const CssmData attrName
,
44 const CssmData attrValue
) :
45 ItemImpl((SecItemClass
) CSSM_DL_DB_RECORD_EXTENDED_ATTRIBUTE
,
46 reinterpret_cast<SecKeychainAttributeList
*>(NULL
),
48 mRecordType(recordType
),
49 mItemID(Allocator::standard(), itemID
.Data
, itemID
.Length
),
50 mAttrName(Allocator::standard(), attrName
.Data
, attrName
.Length
),
51 mAttrValue(Allocator::standard(), attrValue
.Data
, attrValue
.Length
)
56 // db item contstructor
57 ExtendedAttribute::ExtendedAttribute(
58 const Keychain
&keychain
,
59 const PrimaryKey
&primaryKey
,
60 const CssmClient::DbUniqueRecord
&uniqueId
) :
61 ItemImpl(keychain
, primaryKey
, uniqueId
),
63 mItemID(Allocator::standard()),
64 mAttrName(Allocator::standard()),
65 mAttrValue(Allocator::standard())
70 // PrimaryKey item contstructor
71 ExtendedAttribute::ExtendedAttribute(
72 const Keychain
&keychain
,
73 const PrimaryKey
&primaryKey
) :
74 ItemImpl(keychain
, primaryKey
),
76 mItemID(Allocator::standard()),
77 mAttrName(Allocator::standard()),
78 mAttrValue(Allocator::standard())
83 ExtendedAttribute
* ExtendedAttribute::make(const Keychain
&keychain
, const PrimaryKey
&primaryKey
, const CssmClient::DbUniqueRecord
&uniqueId
)
85 ExtendedAttribute
* ea
= new ExtendedAttribute(keychain
, primaryKey
, uniqueId
);
86 keychain
->addItem(primaryKey
, ea
);
92 ExtendedAttribute
* ExtendedAttribute::make(const Keychain
&keychain
, const PrimaryKey
&primaryKey
)
94 ExtendedAttribute
* ea
= new ExtendedAttribute(keychain
, primaryKey
);
95 keychain
->addItem(primaryKey
, ea
);
101 // copy - required due to Item's weird constructor/vendor
102 ExtendedAttribute::ExtendedAttribute(
103 ExtendedAttribute
&extendedAttr
) :
104 ItemImpl(extendedAttr
),
105 mRecordType(extendedAttr
.mRecordType
),
106 mItemID(Allocator::standard()),
107 mAttrName(Allocator::standard()),
108 mAttrValue(Allocator::standard())
110 // CssmData cd = extendedAttr.mItemID;
111 mItemID
.copy(extendedAttr
.mItemID
);
112 // cd = extendedAttr.mAttrName;
113 mAttrName
.copy(extendedAttr
.mAttrName
);
114 // cd = extendedAttr.mAttrValue;
115 mAttrValue
.copy(extendedAttr
.mAttrValue
);
119 ExtendedAttribute::~ExtendedAttribute() _NOEXCEPT
125 ExtendedAttribute::add(Keychain
&keychain
)
127 StLock
<Mutex
>_(mMutex
);
128 // If we already have a Keychain we can't be added.
130 MacOSError::throwMe(errSecDuplicateItem
);
133 CSSMDateTimeUtils::GetCurrentMacLongDateTime(date
);
134 CssmDbAttributeInfo
attrInfo(kSecModDateItemAttr
, CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE
);
135 setAttribute(attrInfo
, date
);
137 Db
db(keychain
->database());
138 // add the item to the (regular) db
141 mUniqueId
= db
->insert(CSSM_DL_DB_RECORD_EXTENDED_ATTRIBUTE
, mDbAttributes
.get(), mData
.get());
143 catch (const CssmError
&e
)
145 if (e
.osStatus() != CSSMERR_DL_INVALID_RECORDTYPE
)
149 * First exposure of this keychain to the extended attribute record type.
150 * Create the relation and try again.
152 db
->createRelation(CSSM_DL_DB_RECORD_EXTENDED_ATTRIBUTE
,
153 "CSSM_DL_DB_RECORD_EXTENDED_ATTRIBUTE",
154 Schema::ExtendedAttributeSchemaAttributeCount
,
155 Schema::ExtendedAttributeSchemaAttributeList
,
156 Schema::ExtendedAttributeSchemaIndexCount
,
157 Schema::ExtendedAttributeSchemaIndexList
);
158 keychain
->keychainSchema()->didCreateRelation(
159 CSSM_DL_DB_RECORD_EXTENDED_ATTRIBUTE
,
160 "CSSM_DL_DB_RECORD_EXTENDED_ATTRIBUTE",
161 Schema::ExtendedAttributeSchemaAttributeCount
,
162 Schema::ExtendedAttributeSchemaAttributeList
,
163 Schema::ExtendedAttributeSchemaIndexCount
,
164 Schema::ExtendedAttributeSchemaIndexList
);
166 mUniqueId
= db
->insert(CSSM_DL_DB_RECORD_EXTENDED_ATTRIBUTE
, mDbAttributes
.get(), mData
.get());
169 mPrimaryKey
= keychain
->makePrimaryKey(CSSM_DL_DB_RECORD_EXTENDED_ATTRIBUTE
, mUniqueId
);
170 mKeychain
= keychain
;
175 /* set up DB attrs based on member vars */
176 void ExtendedAttribute::setupAttrs()
178 StLock
<Mutex
>_(mMutex
);
179 CssmDbAttributeInfo
attrInfo1(kExtendedAttrRecordTypeAttr
, CSSM_DB_ATTRIBUTE_FORMAT_UINT32
);
180 setAttribute(attrInfo1
, (uint32
)mRecordType
);
181 CssmData cd
= mItemID
;
182 CssmDbAttributeInfo
attrInfo2(kExtendedAttrItemIDAttr
, CSSM_DB_ATTRIBUTE_FORMAT_BLOB
);
183 setAttribute(attrInfo2
, cd
);
185 CssmDbAttributeInfo
attrInfo3(kExtendedAttrAttributeNameAttr
, CSSM_DB_ATTRIBUTE_FORMAT_BLOB
);
186 setAttribute(attrInfo3
, cd
);
188 CssmDbAttributeInfo
attrInfo4(kExtendedAttrAttributeValueAttr
, CSSM_DB_ATTRIBUTE_FORMAT_BLOB
);
189 setAttribute(attrInfo4
, cd
);