2 * Copyright (c) 2013-2014 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
25 #include "SOSAccountPriv.h"
28 // DER Encoding utilities
31 static const uint8_t* ccder_decode_null(const uint8_t* der
, const uint8_t *der_end
)
36 size_t payload_size
= 0;
37 const uint8_t *payload
= ccder_decode_tl(CCDER_NULL
, &payload_size
, der
, der_end
);
39 if (NULL
== payload
|| payload_size
!= 0) {
43 return payload
+ payload_size
;
47 static size_t ccder_sizeof_null(void)
49 return ccder_sizeof(CCDER_NULL
, 0);
53 static uint8_t* ccder_encode_null(const uint8_t *der
, uint8_t *der_end
)
55 return ccder_encode_tl(CCDER_NULL
, 0, der
, der_end
);
60 // Encodes data or a zero length data
62 size_t der_sizeof_data_or_null(CFDataRef data
, CFErrorRef
* error
)
65 return der_sizeof_data(data
, error
);
67 return der_sizeof_null(kCFNull
, error
);
71 uint8_t* der_encode_data_or_null(CFDataRef data
, CFErrorRef
* error
, const uint8_t* der
, uint8_t* der_end
)
74 return der_encode_data(data
, error
, der
, der_end
);
76 return der_encode_null(kCFNull
, error
, der
, der_end
);
81 const uint8_t* der_decode_data_or_null(CFAllocatorRef allocator
, CFDataRef
* data
,
83 const uint8_t* der
, const uint8_t* der_end
)
85 CFTypeRef value
= NULL
;
86 der
= der_decode_plist(allocator
, 0, &value
, error
, der
, der_end
);
87 if (value
&& CFGetTypeID(value
) != CFDataGetTypeID()) {
97 // Encodes data or a zero length data
99 size_t der_sizeof_fullpeer_or_null(SOSFullPeerInfoRef full_peer
, CFErrorRef
* error
)
102 return SOSFullPeerInfoGetDEREncodedSize(full_peer
, error
);
104 return ccder_sizeof_null();
108 uint8_t* der_encode_fullpeer_or_null(SOSFullPeerInfoRef full_peer
, CFErrorRef
* error
, const uint8_t* der
, uint8_t* der_end
)
111 return SOSFullPeerInfoEncodeToDER(full_peer
, error
, der
, der_end
);
113 return ccder_encode_null(der
, der_end
);
118 const uint8_t* der_decode_fullpeer_or_null(CFAllocatorRef allocator
, SOSFullPeerInfoRef
* full_peer
,
120 const uint8_t* der
, const uint8_t* der_end
)
124 require_action_quiet(ccder_decode_tag(&tag
, der
, der_end
), fail
, der
= NULL
);
126 require_action_quiet(full_peer
, fail
, der
= NULL
);
128 if (tag
== CCDER_NULL
) {
129 der
= ccder_decode_null(der
, der_end
);
131 *full_peer
= SOSFullPeerInfoCreateFromDER(kCFAllocatorDefault
, error
, &der
, der_end
);
140 // Mark: public_bytes encode/decode
143 size_t der_sizeof_public_bytes(SecKeyRef publicKey
, CFErrorRef
* error
)
145 CFDataRef publicData
= NULL
;
148 SecKeyCopyPublicBytes(publicKey
, &publicData
);
150 size_t size
= der_sizeof_data_or_null(publicData
, error
);
152 CFReleaseNull(publicData
);
157 uint8_t* der_encode_public_bytes(SecKeyRef publicKey
, CFErrorRef
* error
, const uint8_t* der
, uint8_t* der_end
)
159 CFDataRef publicData
= NULL
;
162 SecKeyCopyPublicBytes(publicKey
, &publicData
);
164 uint8_t *result
= der_encode_data_or_null(publicData
, error
, der
, der_end
);
166 CFReleaseNull(publicData
);
171 const uint8_t* der_decode_public_bytes(CFAllocatorRef allocator
, CFIndex algorithmID
, SecKeyRef
* publicKey
, CFErrorRef
* error
, const uint8_t* der
, const uint8_t* der_end
)
173 CFDataRef dataFound
= NULL
;
174 der
= der_decode_data_or_null(allocator
, &dataFound
, error
, der
, der_end
);
176 if (der
&& dataFound
&& publicKey
) {
177 *publicKey
= SecKeyCreateFromPublicData(allocator
, algorithmID
, dataFound
);
179 CFReleaseNull(dataFound
);