2 * Copyright (c) 2002 Apple Computer, Inc. All Rights Reserved.
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
19 // TrustStore.h - Abstract interface to permanent user trust assignments
21 #include <Security/TrustItem.h>
22 #include <Security/Schema.h>
23 #include <Security/SecCFTypes.h>
25 #include <SecurityNssAsn1/secasn1.h>
26 #include <SecurityNssAsn1/SecNssCoder.h>
27 #include <Security/oidscert.h>
31 namespace KeychainCore
{
35 // Construct a UserTrustItem from attributes and initial content
37 UserTrustItem::UserTrustItem(Certificate
*cert
, Policy
*policy
, const TrustData
&trustData
) :
38 ItemImpl(CSSM_DL_DB_RECORD_USER_TRUST
,
39 reinterpret_cast<SecKeychainAttributeList
*>(NULL
),
40 UInt32(sizeof(trustData
)),
41 reinterpret_cast<const void *>(&trustData
)),
42 mCertificate(cert
), mPolicy(policy
)
44 secdebug("usertrust", "create %p (%p,%p) = %d", this, cert
, policy
, trustData
.trust
);
51 UserTrustItem::~UserTrustItem() throw()
53 secdebug("usertrust", "destroy %p", this);
58 // Retrieve the trust value from a UserTrustItem
60 UserTrustItem::TrustData
UserTrustItem::trust()
62 CssmDataContainer data
;
64 if (data
.length() != sizeof(TrustData
))
65 MacOSError::throwMe(errSecInvalidTrustSetting
);
66 return *data
.interpretedAs
<TrustData
>();
71 // Add item to keychain
73 PrimaryKey
UserTrustItem::add(Keychain
&keychain
)
75 // If we already have a Keychain we can't be added.
77 MacOSError::throwMe(errSecDuplicateItem
);
81 CSSM_DB_RECORDTYPE recordType
= mDbAttributes
->recordType();
83 Db
db(keychain
->database());
84 // add the item to the (regular) db
87 mUniqueId
= db
->insert(recordType
, mDbAttributes
.get(), mData
.get());
88 secdebug("usertrust", "%p inserted", this);
90 catch (const CssmError
&e
)
92 if (e
.cssmError() != CSSMERR_DL_INVALID_RECORDTYPE
)
95 // Create the cert relation and try again.
96 secdebug("usertrust", "adding schema relation for user trusts");
97 db
->createRelation(CSSM_DL_DB_RECORD_USER_TRUST
, "CSSM_DL_DB_RECORD_USER_TRUST",
98 Schema::UserTrustSchemaAttributeCount
,
99 Schema::UserTrustSchemaAttributeList
,
100 Schema::UserTrustSchemaIndexCount
,
101 Schema::UserTrustSchemaIndexList
);
102 keychain
->resetSchema();
104 mUniqueId
= db
->insert(recordType
, mDbAttributes
.get(), mData
.get());
105 secdebug("usertrust", "%p inserted now", this);
108 mPrimaryKey
= keychain
->makePrimaryKey(recordType
, mUniqueId
);
109 mKeychain
= keychain
;
114 void UserTrustItem::populateAttributes()
116 CssmAutoData
encodedIndex(CssmAllocator::standard());
117 makeCertIndex(mCertificate
, encodedIndex
);
118 const CssmOid
&policyOid
= mPolicy
->oid();
120 mDbAttributes
->add(Schema::attributeInfo(kSecTrustCertAttr
), encodedIndex
.get());
121 mDbAttributes
->add(Schema::attributeInfo(kSecTrustPolicyAttr
), policyOid
);
126 // An ad-hoc hold-and-destroy accessor for a single-valued certificate field
130 CertField(Certificate
*cert
, const CSSM_OID
&inField
)
131 : certificate(cert
), field(inField
)
132 { mData
= certificate
->copyFirstFieldValue(field
); }
134 ~CertField() { certificate
->releaseFieldValue(field
, mData
); }
136 Certificate
* const certificate
;
137 const CSSM_OID
&field
;
139 operator bool () const { return mData
&& mData
->Data
; }
140 CssmData
&data() const { return CssmData::overlay(*mData
); }
148 // Construct a trust item index.
149 // This is an ASN.1 sequence of issuer and serial number.
156 static const SEC_ASN1Template issuerAndSNTemplate
[] = {
157 { SEC_ASN1_SEQUENCE
, 0, NULL
, sizeof(IssuerAndSN
) },
158 { SEC_ASN1_OCTET_STRING
, offsetof(IssuerAndSN
, issuer
) },
159 { SEC_ASN1_OCTET_STRING
, offsetof(IssuerAndSN
, serial
) },
163 void UserTrustItem::makeCertIndex(Certificate
*cert
, CssmOwnedData
&encodedIndex
)
165 CertField
issuer(cert
, CSSMOID_X509V1IssuerName
);
166 CertField
serial(cert
, CSSMOID_X509V1SerialNumber
);
168 index
.issuer
= issuer
.data();
169 index
.serial
= serial
.data();
170 if (SecNssEncodeItemOdata(&index
, issuerAndSNTemplate
, encodedIndex
))
171 CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR
);
175 } // end namespace KeychainCore
176 } // end namespace Security