+++ /dev/null
-/*
- * Copyright (c) 2002 Apple Computer, Inc. All Rights Reserved.
- *
- * The contents of this file constitute Original Code as defined in and are
- * subject to the Apple Public Source License Version 1.2 (the 'License').
- * You may not use this file except in compliance with the License. Please obtain
- * a copy of the License at http://www.apple.com/publicsource and read it before
- * using this file.
- *
- * This Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
- * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
- * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
- * specific language governing rights and limitations under the License.
- */
-
-//
-// TrustStore.h - Abstract interface to permanent user trust assignments
-//
-#include <Security/TrustItem.h>
-#include <Security/Schema.h>
-#include <Security/SecCFTypes.h>
-
-#include <SecurityNssAsn1/secasn1.h>
-#include <SecurityNssAsn1/SecNssCoder.h>
-#include <Security/oidscert.h>
-
-
-namespace Security {
-namespace KeychainCore {
-
-
-//
-// Construct a UserTrustItem from attributes and initial content
-//
-UserTrustItem::UserTrustItem(Certificate *cert, Policy *policy, const TrustData &trustData) :
- ItemImpl(CSSM_DL_DB_RECORD_USER_TRUST,
- reinterpret_cast<SecKeychainAttributeList *>(NULL),
- UInt32(sizeof(trustData)),
- reinterpret_cast<const void *>(&trustData)),
- mCertificate(cert), mPolicy(policy)
-{
- secdebug("usertrust", "create %p (%p,%p) = %d", this, cert, policy, trustData.trust);
-}
-
-
-//
-// Destroy it
-//
-UserTrustItem::~UserTrustItem() throw()
-{
- secdebug("usertrust", "destroy %p", this);
-}
-
-
-//
-// Retrieve the trust value from a UserTrustItem
-//
-UserTrustItem::TrustData UserTrustItem::trust()
-{
- CssmDataContainer data;
- getData(data);
- if (data.length() != sizeof(TrustData))
- MacOSError::throwMe(errSecInvalidTrustSetting);
- return *data.interpretedAs<TrustData>();
-}
-
-
-//
-// Add item to keychain
-//
-PrimaryKey UserTrustItem::add(Keychain &keychain)
-{
- // If we already have a Keychain we can't be added.
- if (mKeychain)
- MacOSError::throwMe(errSecDuplicateItem);
-
- populateAttributes();
-
- CSSM_DB_RECORDTYPE recordType = mDbAttributes->recordType();
-
- Db db(keychain->database());
- // add the item to the (regular) db
- try
- {
- mUniqueId = db->insert(recordType, mDbAttributes.get(), mData.get());
- secdebug("usertrust", "%p inserted", this);
- }
- catch (const CssmError &e)
- {
- if (e.cssmError() != CSSMERR_DL_INVALID_RECORDTYPE)
- throw;
-
- // Create the cert relation and try again.
- secdebug("usertrust", "adding schema relation for user trusts");
- db->createRelation(CSSM_DL_DB_RECORD_USER_TRUST, "CSSM_DL_DB_RECORD_USER_TRUST",
- Schema::UserTrustSchemaAttributeCount,
- Schema::UserTrustSchemaAttributeList,
- Schema::UserTrustSchemaIndexCount,
- Schema::UserTrustSchemaIndexList);
- keychain->resetSchema();
-
- mUniqueId = db->insert(recordType, mDbAttributes.get(), mData.get());
- secdebug("usertrust", "%p inserted now", this);
- }
-
- mPrimaryKey = keychain->makePrimaryKey(recordType, mUniqueId);
- mKeychain = keychain;
- return mPrimaryKey;
-}
-
-
-void UserTrustItem::populateAttributes()
-{
- CssmAutoData encodedIndex(CssmAllocator::standard());
- makeCertIndex(mCertificate, encodedIndex);
- const CssmOid &policyOid = mPolicy->oid();
-
- mDbAttributes->add(Schema::attributeInfo(kSecTrustCertAttr), encodedIndex.get());
- mDbAttributes->add(Schema::attributeInfo(kSecTrustPolicyAttr), policyOid);
-}
-
-
-//
-// An ad-hoc hold-and-destroy accessor for a single-valued certificate field
-//
-class CertField {
-public:
- CertField(Certificate *cert, const CSSM_OID &inField)
- : certificate(cert), field(inField)
- { mData = certificate->copyFirstFieldValue(field); }
-
- ~CertField() { certificate->releaseFieldValue(field, mData); }
-
- Certificate * const certificate;
- const CSSM_OID &field;
-
- operator bool () const { return mData && mData->Data; }
- CssmData &data() const { return CssmData::overlay(*mData); }
-
-private:
- CSSM_DATA_PTR mData;
-};
-
-
-//
-// Construct a trust item index.
-// This is an ASN.1 sequence of issuer and serial number.
-//
-struct IssuerAndSN {
- CSSM_DATA issuer;
- CSSM_DATA serial;
-};
-
-static const SEC_ASN1Template issuerAndSNTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(IssuerAndSN) },
- { SEC_ASN1_OCTET_STRING, offsetof(IssuerAndSN, issuer) },
- { SEC_ASN1_OCTET_STRING, offsetof(IssuerAndSN, serial) },
- { 0 }
-};
-
-void UserTrustItem::makeCertIndex(Certificate *cert, CssmOwnedData &encodedIndex)
-{
- CertField issuer(cert, CSSMOID_X509V1IssuerName);
- CertField serial(cert, CSSMOID_X509V1SerialNumber);
- IssuerAndSN index;
- index.issuer = issuer.data();
- index.serial = serial.data();
- if (SecNssEncodeItemOdata(&index, issuerAndSNTemplate, encodedIndex))
- CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR);
-}
-
-
-} // end namespace KeychainCore
-} // end namespace Security