1/*
2 * Copyright (c) 2002-2007,2012 Apple 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// Certificate.h - Certificate objects
26//
27#ifndef _SECURITY_CERTIFICATE_H_
28#define _SECURITY_CERTIFICATE_H_
29
30#include <security_keychain/Item.h>
31
32#include <security_keychain/StorageManager.h>
33// @@@ This should not be here.
34#include <Security/SecBase.h>
35#include <security_cdsa_client/clclient.h>
36
37namespace Security
38{
39
40namespace KeychainCore
41{
42
43class KeyItem;
44
45class Certificate : public ItemImpl
46{
47	NOCOPY(Certificate)
48public:
49	SECCFFUNCTIONS(Certificate, SecCertificateRef, errSecInvalidItemRef, gTypes().Certificate)
50
51	static CL clForType(CSSM_CERT_TYPE type);
52
53	// new item constructor
54    Certificate(const CSSM_DATA &data, CSSM_CERT_TYPE type, CSSM_CERT_ENCODING encoding);
55
56private:
57	// db item constructor
58    Certificate(const Keychain &keychain, const PrimaryKey &primaryKey, const CssmClient::DbUniqueRecord &uniqueId);
59
60	// PrimaryKey item constructor
61    Certificate(const Keychain &keychain, const PrimaryKey &primaryKey);
62
63public:
64	static Certificate* make(const Keychain &keychain, const PrimaryKey &primaryKey, const CssmClient::DbUniqueRecord &uniqueId);
65	static Certificate* make(const Keychain &keychain, const PrimaryKey &primaryKey);
66
67	Certificate(Certificate &certificate);
68    virtual ~Certificate();
69
70	virtual void update();
71	virtual Item copyTo(const Keychain &keychain, Access *newAccess = NULL);
72	virtual void didModify(); // Forget any attributes and data we just wrote to the db
73
74    const CssmData &data();
75    CSSM_CERT_TYPE type();
76	CSSM_CERT_ENCODING encoding();
77	CFDataRef sha1Hash();
78	CFStringRef commonName();
79	CFStringRef distinguishedName(const CSSM_OID *sourceOid, const CSSM_OID *componentOid);
80	CFStringRef copyFirstEmailAddress();
81	CFArrayRef copyEmailAddresses();
82	CFArrayRef copyDNSNames();
83    const CSSM_X509_NAME_PTR subjectName();
84    const CSSM_X509_NAME_PTR issuerName();
85	const CSSM_X509_ALGORITHM_IDENTIFIER_PTR algorithmID();
86   	CSSM_CL_HANDLE clHandle();
87	void inferLabel(bool addLabel, CFStringRef *rtnString = NULL);
88	SecPointer<KeyItem> publicKey();
89	const CssmData &publicKeyHash();
90	const CssmData &subjectKeyIdentifier();
91
92	static KCCursor cursorForIssuerAndSN(const StorageManager::KeychainList &keychains, const CssmData &issuer, const CssmData &serialNumber);
93	static KCCursor cursorForSubjectKeyID(const StorageManager::KeychainList &keychains, const CssmData &subjectKeyID);
94	static KCCursor cursorForEmail(const StorageManager::KeychainList &keychains, const char *emailAddress);
95	static KCCursor cursorForIssuerAndSN_CF(const StorageManager::KeychainList &keychains, CFDataRef issuer, CFDataRef serialNumber);
96
97	SecPointer<Certificate> findInKeychain(const StorageManager::KeychainList &keychains);
98	static SecPointer<Certificate> findByIssuerAndSN(const StorageManager::KeychainList &keychains, const CssmData &issuer, const CssmData &serialNumber);
99	static SecPointer<Certificate> findBySubjectKeyID(const StorageManager::KeychainList &keychains, const CssmData &subjectKeyID);
100	static SecPointer<Certificate> findByEmail(const StorageManager::KeychainList &keychains, const char *emailAddress);
101
102	static void normalizeEmailAddress(CSSM_DATA &emailAddress);
103	static void getNames(CSSM_DATA_PTR *sanValues, CSSM_DATA_PTR snValue, CE_GeneralNameType generalNameType, std::vector<CssmData> &names);
104
105	bool operator < (Certificate &other);
106	bool operator == (Certificate &other);
107
108	virtual CFHashCode hash();
109
110public:
111	CSSM_DATA_PTR copyFirstFieldValue(const CSSM_OID &field);
112	void releaseFieldValue(const CSSM_OID &field, CSSM_DATA_PTR fieldValue);
113
114	CSSM_DATA_PTR *copyFieldValues(const CSSM_OID &field);
115	void releaseFieldValues(const CSSM_OID &field, CSSM_DATA_PTR *fieldValues);
116	Boolean isSelfSigned();
117
118protected:
119	virtual void willRead();
120	virtual PrimaryKey add(Keychain &keychain);
121	CSSM_HANDLE certHandle();
122
123	void addParsedAttribute(const CSSM_DB_ATTRIBUTE_INFO &info, const CSSM_OID &field);
124
125	void addSubjectKeyIdentifier();
126	void populateAttributes();
127
128private:
129	bool mHaveTypeAndEncoding;
130	bool mPopulated;
131    CSSM_CERT_TYPE mType;
132	CSSM_CERT_ENCODING mEncoding;
133    CssmClient::CL mCL;
134	CSSM_HANDLE mCertHandle;
135	CssmData mPublicKeyHash;
136	uint8 mPublicKeyHashBytes[20];
137	CssmData mSubjectKeyID;
138	uint8 mSubjectKeyIDBytes[20];
139	CSSM_DATA_PTR mV1SubjectPublicKeyCStructValue; // Hack to prevent algorithmID() from leaking.
140    CSSM_DATA_PTR mV1SubjectNameCStructValue;
141    CSSM_DATA_PTR mV1IssuerNameCStructValue;
142	CFDataRef mSha1Hash;
143};
144
145} // end namespace KeychainCore
146
147} // end namespace Security
148
149#endif // !_SECURITY_CERTIFICATE_H_
150