5 // Created by Richard Murphy on 3/3/15.
9 #include "SOSRingDER.h"
10 #include <AssertMacros.h>
12 #include "keychain/SecureObjectSync/SOSInternal.h"
13 #include "keychain/SecureObjectSync/SOSPeer.h"
14 #include "keychain/SecureObjectSync/SOSPeerInfoInternal.h"
15 #include "keychain/SecureObjectSync/SOSPeerInfoCollections.h"
16 #include "keychain/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>
39 #include "SOSRingUtils.h"
41 size_t SOSRingGetDEREncodedSize(SOSRingRef ring
, CFErrorRef
*error
) {
42 SOSRingAssertStable(ring
);
43 size_t total_payload
= 0;
45 require_quiet(accumulate_size(&total_payload
, der_sizeof_dictionary((CFDictionaryRef
) ring
->unSignedInformation
, error
)), fail
);
46 require_quiet(accumulate_size(&total_payload
, der_sizeof_dictionary((CFDictionaryRef
) ring
->signedInformation
, error
)), fail
);
47 require_quiet(accumulate_size(&total_payload
, der_sizeof_dictionary((CFDictionaryRef
) ring
->signatures
, error
)), fail
);
48 require_quiet(accumulate_size(&total_payload
, der_sizeof_dictionary((CFDictionaryRef
) ring
->data
, error
)), fail
);
50 return ccder_sizeof(CCDER_CONSTRUCTED_SEQUENCE
, total_payload
);
52 SecCFDERCreateError(kSecDERErrorUnknownEncoding
, CFSTR("don't know how to encode"), NULL
, error
);
56 uint8_t* SOSRingEncodeToDER(SOSRingRef ring
, CFErrorRef
* error
, const uint8_t* der
, uint8_t* der_end
) {
57 return ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE
, der_end
, der
,
58 der_encode_dictionary(ring
->unSignedInformation
, error
, der
,
59 der_encode_dictionary(ring
->signedInformation
, error
, der
,
60 der_encode_dictionary(ring
->signatures
, error
, der
,
61 der_encode_dictionary(ring
->data
, error
, der
, der_end
)))));
64 CFDataRef
SOSRingCopyEncodedData(SOSRingRef ring
, CFErrorRef
*error
) {
65 return CFDataCreateWithDER(kCFAllocatorDefault
, SOSRingGetDEREncodedSize(ring
, error
), ^uint8_t*(size_t size
, uint8_t *buffer
) {
66 return SOSRingEncodeToDER(ring
, error
, buffer
, (uint8_t *) buffer
+ size
);
70 SOSRingRef
SOSRingCreateFromDER(CFErrorRef
* error
, const uint8_t** der_p
, const uint8_t *der_end
) {
71 SOSRingRef ring
= SOSRingAllocate();
72 SOSRingRef retval
= NULL
;
73 const uint8_t *sequence_end
;
74 CFDictionaryRef unSignedInformation
= NULL
;
75 CFDictionaryRef signedInformation
= NULL
;
76 CFDictionaryRef signatures
= NULL
;
77 CFDictionaryRef data
= NULL
;
79 require_action_quiet(ring
, errOut
, secnotice("ring", "Unable to allocate ring"));
80 *der_p
= ccder_decode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE
, &sequence_end
, *der_p
, der_end
);
81 *der_p
= der_decode_dictionary(ALLOCATOR
, &unSignedInformation
, error
, *der_p
, sequence_end
);
82 *der_p
= der_decode_dictionary(ALLOCATOR
, &signedInformation
, error
, *der_p
, sequence_end
);
83 *der_p
= der_decode_dictionary(ALLOCATOR
, &signatures
, error
, *der_p
, sequence_end
);
84 *der_p
= der_decode_dictionary(ALLOCATOR
, &data
, error
, *der_p
, sequence_end
);
86 require_action_quiet(*der_p
, errOut
, secnotice("ring", "Unable to decode DER"));
87 require_action_quiet(*der_p
== der_end
, errOut
, secnotice("ring", "Unable to decode DER"));
89 ring
->unSignedInformation
= CFDictionaryCreateMutableCopy(ALLOCATOR
, 0, unSignedInformation
);
90 ring
->signedInformation
= CFDictionaryCreateMutableCopy(ALLOCATOR
, 0, signedInformation
);
91 ring
->signatures
= CFDictionaryCreateMutableCopy(ALLOCATOR
, 0, signatures
);
92 ring
->data
= CFDictionaryCreateMutableCopy(ALLOCATOR
, 0, data
);
97 CFReleaseNull(unSignedInformation
);
98 CFReleaseNull(signedInformation
);
99 CFReleaseNull(signatures
);
106 SOSRingRef
SOSRingCreateFromData(CFErrorRef
* error
, CFDataRef ring_data
) {
107 const uint8_t *der
= CFDataGetBytePtr(ring_data
);
108 CFIndex len
= CFDataGetLength(ring_data
);
109 return SOSRingCreateFromDER(error
, &der
, der
+len
);