initial import
[vuplus_webkit] / Source / WebKit2 / Shared / mac / SecKeychainItemRequestData.cpp
1 /*
2  * Copyright (C) 2011 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "SecKeychainItemRequestData.h"
28
29 #include "ArgumentCoders.h"
30 #include "ArgumentCodersCF.h"
31
32 namespace WebKit {
33
34 SecKeychainItemRequestData::SecKeychainItemRequestData()
35     : m_itemClass(0)
36 {
37 }
38
39 SecKeychainItemRequestData::SecKeychainItemRequestData(SecKeychainItemRef item, SecKeychainAttributeList* attrList)
40     : m_keychainItem(item)
41     , m_itemClass(0)
42 {
43     initializeWithAttributeList(attrList);
44 }
45
46 SecKeychainItemRequestData::SecKeychainItemRequestData(SecKeychainItemRef item, SecKeychainAttributeList* attrList, UInt32 length, const void* data)
47     : m_keychainItem(item)
48     , m_itemClass(0)
49     , m_dataReference(static_cast<const uint8_t*>(data), length)
50 {
51     initializeWithAttributeList(attrList);
52 }
53
54
55 SecKeychainItemRequestData::SecKeychainItemRequestData(SecItemClass itemClass, SecKeychainAttributeList* attrList, UInt32 length, const void* data)
56     : m_itemClass(itemClass)
57     , m_dataReference(static_cast<const uint8_t*>(data), length)
58 {
59     initializeWithAttributeList(attrList);
60 }
61
62 void SecKeychainItemRequestData::initializeWithAttributeList(SecKeychainAttributeList* attrList)
63 {
64     if (!attrList)
65         return;
66     m_keychainAttributes.reserveCapacity(attrList->count);
67     for (size_t i = 0; i < attrList->count; ++i)
68         m_keychainAttributes.append(KeychainAttribute(attrList->attr[i]));
69 }
70
71 SecKeychainItemRequestData::~SecKeychainItemRequestData()
72 {
73 #ifndef NDEBUG
74     if (!m_attributeList)
75         return;
76
77     // If this request was for SecKeychainItemModifyContent:
78     //   - The data pointers should've been populated by this SecKeychainItemRequestData,
79     //     and should match the data pointers contained in the corresponding CFDataRef
80     // If this request was for SecKeychainItemCopyContent:
81     //   - Security APIs should've filled in the data in the AttributeList and that data 
82     //     should've been freed by SecKeychainItemFreeContent.
83     for (size_t i = 0; i < m_attributeList->count; ++i) {
84         if (m_keychainAttributes[i].data)
85             ASSERT(m_attributeList->attr[i].data == CFDataGetBytePtr(m_keychainAttributes[i].data.get()));
86         else
87             ASSERT(!m_attributeList->attr[i].data);
88     }
89 #endif
90 }
91
92 SecKeychainAttributeList* SecKeychainItemRequestData::attributeList() const
93 {
94     if (m_attributeList || m_keychainAttributes.isEmpty())
95         return m_attributeList.get();
96     
97     m_attributeList = adoptPtr(new SecKeychainAttributeList);
98     m_attributeList->count = m_keychainAttributes.size();
99     m_attributes = adoptArrayPtr(new SecKeychainAttribute[m_attributeList->count]);
100     m_attributeList->attr = m_attributes.get();
101
102     for (size_t i = 0; i < m_attributeList->count; ++i) {
103         m_attributeList->attr[i].tag = m_keychainAttributes[i].tag;
104         if (!m_keychainAttributes[i].data) {
105             m_attributeList->attr[i].length = 0;
106             m_attributeList->attr[i].data = 0;
107             continue;
108         }
109         
110         m_attributeList->attr[i].length = CFDataGetLength(m_keychainAttributes[i].data.get());
111         m_attributeList->attr[i].data = const_cast<void*>(static_cast<const void*>(CFDataGetBytePtr(m_keychainAttributes[i].data.get())));
112     }
113     
114     return m_attributeList.get();
115 }
116
117 void SecKeychainItemRequestData::encode(CoreIPC::ArgumentEncoder* encoder) const
118 {
119     encoder->encodeBool(m_keychainItem);
120     if (m_keychainItem)
121         CoreIPC::encode(encoder, m_keychainItem.get());
122
123     encoder->encodeUInt32(m_keychainAttributes.size());
124     for (size_t i = 0, count = m_keychainAttributes.size(); i < count; ++i)
125         CoreIPC::encode(encoder, m_keychainAttributes[i]);
126     
127     encoder->encodeUInt64(m_itemClass);
128     m_dataReference.encode(encoder);
129 }
130
131 bool SecKeychainItemRequestData::decode(CoreIPC::ArgumentDecoder* decoder, SecKeychainItemRequestData& secKeychainItemRequestData)
132 {
133     bool hasKeychainItem;
134     if (!decoder->decodeBool(hasKeychainItem))
135         return false;
136
137     if (hasKeychainItem && !CoreIPC::decode(decoder, secKeychainItemRequestData.m_keychainItem))
138         return false;
139     
140     uint32_t attributeCount;
141     if (!decoder->decodeUInt32(attributeCount))
142         return false;
143     
144     ASSERT(secKeychainItemRequestData.m_keychainAttributes.isEmpty());
145     secKeychainItemRequestData.m_keychainAttributes.reserveCapacity(attributeCount);
146     
147     for (size_t i = 0; i < attributeCount; ++i) {
148         KeychainAttribute attribute;
149         if (!CoreIPC::decode(decoder, attribute))
150             return false;
151         secKeychainItemRequestData.m_keychainAttributes.append(attribute);
152     }
153     
154     uint64_t itemClass;
155     if (!decoder->decodeUInt64(itemClass))
156         return false;
157     
158     secKeychainItemRequestData.m_itemClass = static_cast<SecItemClass>(itemClass);
159
160     if (!CoreIPC::DataReference::decode(decoder, secKeychainItemRequestData.m_dataReference))
161         return false;
162         
163     return true;
164 }
165
166 } // namespace WebKit