]> git.saurik.com Git - apple/security.git/blob - Keychain/PrimaryKey.cpp
Security-179.tar.gz
[apple/security.git] / Keychain / PrimaryKey.cpp
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
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
8 * using this file.
9 *
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.
16 */
17
18
19 //
20 // PrimaryKey.cpp
21 //
22
23 #include "PrimaryKey.h"
24
25 using namespace KeychainCore;
26 using namespace CssmClient;
27
28
29 PrimaryKeyImpl::PrimaryKeyImpl(const CSSM_DATA &data)
30 : CssmDataContainer(data.Data, data.Length)
31 {
32
33 //@@@ do bounds checking here, throw if invalid
34
35 }
36
37 PrimaryKeyImpl::PrimaryKeyImpl(const DbAttributes &primaryKeyAttrs)
38 {
39 Length = sizeof(uint32);
40 for (uint32 ix = 0; ix < primaryKeyAttrs.size(); ++ix)
41 {
42 if (primaryKeyAttrs.at(ix).size() == 0)
43 MacOSError::throwMe(errSecInvalidKeychain);
44
45 Length += sizeof(uint32) + primaryKeyAttrs.at(ix).Value[0].Length;
46 }
47
48 // Careful with exceptions
49 Data = mAllocator.alloc<uint8>(Length);
50 uint8 *p = Data;
51
52 putUInt32(p, primaryKeyAttrs.recordType());
53 for (uint32 ix = 0; ix < primaryKeyAttrs.size(); ++ix)
54 {
55 uint32 len = primaryKeyAttrs.at(ix).Value[0].Length;
56 putUInt32(p, len);
57 memcpy(p, primaryKeyAttrs.at(ix).Value[0].Data, len);
58 p += len;
59 }
60 }
61
62 CssmClient::DbCursor
63 PrimaryKeyImpl::createCursor(const Keychain &keychain)
64 {
65 DbCursor cursor(keychain->database());
66
67 // @@@ Set up cursor to find item with this.
68 uint8 *p = Data;
69 uint32 left = Length;
70 if (left < sizeof(*p))
71 MacOSError::throwMe(errSecNoSuchAttr); // XXX Not really but whatever.
72
73 CSSM_DB_RECORDTYPE rt = getUInt32(p, left);
74 const CssmAutoDbRecordAttributeInfo &infos = keychain->primaryKeyInfosFor(rt);
75
76 cursor->recordType(rt);
77 cursor->conjunctive(CSSM_DB_AND);
78 for (uint32 ix = 0; ix < infos.size(); ++ix)
79 {
80 uint32 len = getUInt32(p, left);
81
82 if (left < len)
83 MacOSError::throwMe(errSecNoSuchAttr); // XXX Not really but whatever.
84
85 CssmData value(p, len);
86 left -= len;
87 p += len;
88
89 cursor->add(CSSM_DB_EQUAL, infos.at(ix), value);
90 }
91
92 return cursor;
93 }
94
95
96 void
97 PrimaryKeyImpl::putUInt32(uint8 *&p, uint32 value)
98 {
99 *p++ = (value >> 24);
100 *p++ = (value >> 16) & 0xff;
101 *p++ = (value >> 8) & 0xff;
102 *p++ = value & 0xff;
103 }
104
105 uint32
106 PrimaryKeyImpl::getUInt32(uint8 *&p, uint32 &left) const
107 {
108 if (left < sizeof(uint32))
109 MacOSError::throwMe(errSecNoSuchAttr); // XXX Not really but whatever.
110
111
112 // @@@ Assumes data written in big endian.
113 uint32 value = (p[0] << 24) + (p[1] << 16) + (p[2] << 8) + p[3];
114 p += sizeof(uint32);
115 left -= sizeof(uint32);
116 return value;
117 }
118
119
120
121 CSSM_DB_RECORDTYPE
122 PrimaryKeyImpl::recordType() const
123 {
124 uint8 *data = Data;
125 uint32 length = Length;
126 return getUInt32(data, length);
127 }