5 // Created by Richard Murphy on 3/3/15.
9 #include "SOSRingDER.h"
10 #include <AssertMacros.h>
12 #include <Security/SecureObjectSync/SOSInternal.h>
13 #include <Security/SecureObjectSync/SOSPeer.h>
14 #include <Security/SecureObjectSync/SOSPeerInfoInternal.h>
15 #include <Security/SecureObjectSync/SOSPeerInfoCollections.h>
16 #include <Security/SecureObjectSync/SOSCircle.h>
17 #include <Security/SecFramework.h>
19 #include <Security/SecKey.h>
20 #include <Security/SecKeyPriv.h>
21 #include <CoreFoundation/CoreFoundation.h>
23 #include <utilities/SecCFWrappers.h>
25 //#include "ckdUtilities.h"
27 #include <corecrypto/ccder.h>
28 #include <corecrypto/ccdigest.h>
29 #include <corecrypto/ccsha2.h>
32 #include <utilities/der_plist.h>
33 #include <utilities/der_plist_internal.h>
34 #include <corecrypto/ccder.h>
35 #include <utilities/der_date.h>
40 #include "SOSRingUtils.h"
42 size_t SOSRingGetDEREncodedSize(SOSRingRef ring
, CFErrorRef
*error
) {
43 SOSRingAssertStable(ring
);
44 size_t total_payload
= 0;
46 require_quiet(accumulate_size(&total_payload
, der_sizeof_dictionary((CFDictionaryRef
) ring
->unSignedInformation
, error
)), fail
);
47 require_quiet(accumulate_size(&total_payload
, der_sizeof_dictionary((CFDictionaryRef
) ring
->signedInformation
, error
)), fail
);
48 require_quiet(accumulate_size(&total_payload
, der_sizeof_dictionary((CFDictionaryRef
) ring
->signatures
, error
)), fail
);
49 require_quiet(accumulate_size(&total_payload
, der_sizeof_dictionary((CFDictionaryRef
) ring
->data
, error
)), fail
);
51 return ccder_sizeof(CCDER_CONSTRUCTED_SEQUENCE
, total_payload
);
53 SecCFDERCreateError(kSecDERErrorUnknownEncoding
, CFSTR("don't know how to encode"), NULL
, error
);
57 uint8_t* SOSRingEncodeToDER(SOSRingRef ring
, CFErrorRef
* error
, const uint8_t* der
, uint8_t* der_end
) {
58 return ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE
, der_end
, der
,
59 der_encode_dictionary(ring
->unSignedInformation
, error
, der
,
60 der_encode_dictionary(ring
->signedInformation
, error
, der
,
61 der_encode_dictionary(ring
->signatures
, error
, der
,
62 der_encode_dictionary(ring
->data
, error
, der
, der_end
)))));
65 CFDataRef
SOSRingCopyEncodedData(SOSRingRef ring
, CFErrorRef
*error
) {
66 size_t size
= SOSRingGetDEREncodedSize(ring
, error
);
67 if (size
== 0) return NULL
;
70 uint8_t* start
= SOSRingEncodeToDER(ring
, error
, buffer
, buffer
+ sizeof(buffer
));
71 CFDataRef result
= CFDataCreate(kCFAllocatorDefault
, start
, size
);
75 SOSRingRef
SOSRingCreateFromDER(CFErrorRef
* error
, const uint8_t** der_p
, const uint8_t *der_end
) {
76 SOSRingRef ring
= SOSRingAllocate();
77 SOSRingRef retval
= NULL
;
78 const uint8_t *sequence_end
;
79 CFDictionaryRef unSignedInformation
= NULL
;
80 CFDictionaryRef signedInformation
= NULL
;
81 CFDictionaryRef signatures
= NULL
;
82 CFDictionaryRef data
= NULL
;
84 require_action_quiet(ring
, errOut
, secnotice("ring", "Unable to allocate ring"));
85 *der_p
= ccder_decode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE
, &sequence_end
, *der_p
, der_end
);
86 *der_p
= der_decode_dictionary(ALLOCATOR
, kCFPropertyListImmutable
, &unSignedInformation
, error
, *der_p
, sequence_end
);
87 *der_p
= der_decode_dictionary(ALLOCATOR
, kCFPropertyListImmutable
, &signedInformation
, error
, *der_p
, sequence_end
);
88 *der_p
= der_decode_dictionary(ALLOCATOR
, kCFPropertyListImmutable
, &signatures
, error
, *der_p
, sequence_end
);
89 *der_p
= der_decode_dictionary(ALLOCATOR
, kCFPropertyListImmutable
, &data
, error
, *der_p
, sequence_end
);
91 require_action_quiet(*der_p
, errOut
, secnotice("ring", "Unable to decode DER"));
92 require_action_quiet(*der_p
== der_end
, errOut
, secnotice("ring", "Unable to decode DER"));
94 ring
->unSignedInformation
= CFDictionaryCreateMutableCopy(ALLOCATOR
, 0, unSignedInformation
);
95 ring
->signedInformation
= CFDictionaryCreateMutableCopy(ALLOCATOR
, 0, signedInformation
);
96 ring
->signatures
= CFDictionaryCreateMutableCopy(ALLOCATOR
, 0, signatures
);
97 ring
->data
= CFDictionaryCreateMutableCopy(ALLOCATOR
, 0, data
);
102 CFReleaseNull(unSignedInformation
);
103 CFReleaseNull(signedInformation
);
104 CFReleaseNull(signatures
);
111 SOSRingRef
SOSRingCreateFromData(CFErrorRef
* error
, CFDataRef ring_data
) {
112 const uint8_t *der
= CFDataGetBytePtr(ring_data
);
113 CFIndex len
= CFDataGetLength(ring_data
);
114 return SOSRingCreateFromDER(error
, &der
, der
+len
);