1// 2// sc-60-peer.c 3// sec 4// 5// Created by Michael Brouwer on 8/2/12. 6// Copyright 2012 Apple Inc. All rights reserved. 7// 8 9#include <SecureObjectSync/SOSPeer.h> 10 11#include "SOSCircle_regressions.h" 12 13#include <corecrypto/ccsha2.h> 14 15#include <Security/SecBase64.h> 16 17#include <utilities/SecCFWrappers.h> 18 19#include <stdint.h> 20 21static int kTestTestCount = 13; 22 23struct SOSTestTransport { 24 struct SOSTransport t; 25 unsigned t_msg_count; 26 uint8_t digest[CCSHA256_OUTPUT_SIZE]; 27}; 28 29 30static void tests(void) 31{ 32 const unsigned kSOSPeerVersion = 0; 33 34 CFErrorRef error = NULL; 35 SOSPeerRef peer; 36 37 /* Create peer test. */ 38 CFStringRef peer_id = CFSTR("peer 60"); 39 40 __block unsigned msg_count = 0; 41 uint8_t msg_digest_buffer[CCSHA256_OUTPUT_SIZE]; 42 uint8_t *msg_digest = msg_digest_buffer; 43 44 SOSPeerSendBlock sendBlock = ^bool (CFDataRef message, CFErrorRef *error) { 45 size_t msglen = CFDataGetLength(message); 46 const uint8_t *msg = CFDataGetBytePtr(message); 47 const struct ccdigest_info *sha256 = ccsha256_di(); 48 if (msg_count++ == 0) { 49 /* message n=0 */ 50 ccdigest(sha256, msglen, msg, msg_digest); 51 } else { 52 /* message n=n+1 */ 53 ccdigest_di_decl(sha256, sha256_ctx); 54 ccdigest_init(sha256, sha256_ctx); 55 ccdigest_update(sha256, sha256_ctx, sizeof(msg_digest_buffer), msg_digest); 56 ccdigest_update(sha256, sha256_ctx, msglen, msg); 57 ccdigest_final(sha256, sha256_ctx, msg_digest); 58 } 59 size_t encmaxlen = SecBase64Encode(msg, msglen, NULL, 0); 60 CFMutableDataRef encoded = CFDataCreateMutable(NULL, encmaxlen); 61 CFDataSetLength(encoded, encmaxlen); 62 SecBase64Result rc; 63 char *enc = (char *)CFDataGetMutableBytePtr(encoded); 64#ifndef NDEBUG 65 size_t enclen = 66#endif 67 SecBase64Encode2(msg, msglen, 68 enc, 69 encmaxlen, kSecB64_F_LINE_LEN_USE_PARAM, 70 64, &rc); 71 assert(enclen < INT32_MAX); 72 73// printf("=== BEGIN SOSMESSAGE ===\n%.*s\n=== END SOSMESSAGE ===\n", (int)enclen, enc); 74 75 CFRelease(encoded); 76 return true; 77 }; 78 79 80 ok(peer = SOSPeerCreateSimple(peer_id, kSOSPeerVersion, &error, sendBlock), 81 "create peer: %@", error); 82 CFReleaseNull(error); 83 84 /* Send a test message. */ 85 is((int)msg_count, 0, "no message sent yet"); 86 size_t msglen = 10; 87 uint8_t msg[msglen]; 88 memcpy(msg, "0123456789", msglen); 89 CFDataRef message = CFDataCreate(NULL, msg, msglen); 90 ok(SOSPeerSendMessage(peer, message, &error), 91 "send message to peer: %@", error); 92 CFReleaseNull(error); 93 is((int)msg_count, 1, "We sent %d/1 messages", msg_count); 94 CFRelease(message); 95 96 /* Check the peer's version. */ 97 is(SOSPeerGetVersion(peer), kSOSPeerVersion, "version is correct"); 98 99 /* Get the peer's manifest. */ 100 SOSManifestRef manifest = SOSPeerCopyManifest(peer, &error); 101 ok(manifest == NULL, "No manifest yet for this peer: %@", error); 102 CFReleaseNull(error); 103 CFReleaseNull(manifest); 104 105 /* Get the peer's manifest digest. */ 106 CFDataRef digest = SOSPeerCopyManifestDigest(peer, &error); 107 ok(digest == NULL, "No digest yet for this peer's manifest: %@", error); 108 CFReleaseNull(error); 109 CFReleaseNull(digest); 110 111 ok(manifest = SOSManifestCreateWithBytes(NULL, 0, &error), "Create empty manifest: %@", error); 112 CFReleaseNull(error); 113 ok(SOSPeerSetManifest(peer, manifest, &error), "Set empty manifest on peer: %@", error); 114 CFReleaseNull(error); 115 116 /* Get the peer's empty manifest digest. */ 117 digest = SOSPeerCopyManifestDigest(peer, &error); 118 ok(digest, "Got a digest: %@ this peer's manifest: %@", digest, error); 119 CFReleaseNull(error); 120 121 /* Clean up. */ 122 SOSPeerDispose(peer); 123 124 SOSPeerRef reinflated_peer = NULL; 125 ok(reinflated_peer = SOSPeerCreateSimple(peer_id, kSOSPeerVersion, &error, sendBlock), 126 "create peer: %@", error); 127 CFReleaseNull(error); 128 129 CFDataRef digestAfterReinflate = SOSPeerCopyManifestDigest(reinflated_peer, &error); 130 ok(digest != NULL, "Got NULL after reinflate (%@)", error); 131 ok(CFEqual(digest, digestAfterReinflate), "Compare digest after reinflate, before: %@ after: %@", digest, digestAfterReinflate); 132 CFReleaseNull(error); 133 134 SOSPeerDispose(reinflated_peer); 135 136 CFReleaseNull(digestAfterReinflate); 137 CFReleaseNull(digest); 138} 139 140int sc_60_peer(int argc, char *const *argv) 141{ 142 plan_tests(kTestTestCount); 143 144 tests(); 145 146 return 0; 147} 148