]> git.saurik.com Git - apple/security.git/blob - keychain/ot/OTBottledPeerSigned.m
Security-58286.51.6.tar.gz
[apple/security.git] / keychain / ot / OTBottledPeerSigned.m
1 /*
2 * Copyright (c) 2017 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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
11 * file.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 #if OCTAGON
25 #import <Foundation/Foundation.h>
26 #import "OTBottledPeer.h"
27 #import "OTBottledPeerSigned.h"
28 #import "SFPublicKey+SPKI.h"
29 #import "OTIdentity.h"
30
31 #import <SecurityFoundation/SFEncryptionOperation.h>
32 #import <SecurityFoundation/SFSigningOperation.h>
33 #import <SecurityFoundation/SFDigestOperation.h>
34 #import <SecurityFoundation/SFKey.h>
35 #import <SecurityFoundation/SFKey_Private.h>
36
37 #import <corecrypto/cchkdf.h>
38 #import <corecrypto/ccsha2.h>
39 #import <corecrypto/ccec.h>
40
41 #include <utilities/debugging.h>
42
43 @interface OTBottledPeerSigned ()
44 @property (nonatomic, strong) OTBottledPeer* bp;
45 @property (nonatomic, strong) NSData* signatureUsingEscrowKey;
46 @property (nonatomic, strong) NSData* signatureUsingPeerKey;
47 @property (nonatomic, strong) NSData* escrowSigningPublicKey;
48 @end
49
50 @implementation OTBottledPeerSigned
51
52 // Create signatures
53 - (nullable instancetype) initWithBottledPeer:(OTBottledPeer*)bp
54 escrowedSigningKey:(SFECKeyPair *)escrowedSigningKey
55 peerSigningKey:(SFECKeyPair *)peerSigningKey
56 error:(NSError**)error
57 {
58 self = [super init];
59 if (self) {
60 _bp = bp;
61 _escrowSigningSPKI = [escrowedSigningKey.publicKey asSPKI];
62 SFEC_X962SigningOperation* xso = [OTBottledPeerSigned signingOperation];
63 _signatureUsingEscrowKey = [xso sign:bp.data withKey:escrowedSigningKey error:error].signature;
64 if (!_signatureUsingEscrowKey) {
65 return nil;
66 }
67 _signatureUsingPeerKey = [xso sign:bp.data withKey:peerSigningKey error:error].signature;
68 if (!_signatureUsingPeerKey) {
69 return nil;
70 }
71 }
72 return self;
73 }
74
75 -(NSString*) escrowSigningPublicKeyHash
76 {
77 const struct ccdigest_info *di = ccsha384_di();
78 NSMutableData* result = [[NSMutableData alloc] initWithLength:ccsha384_di()->output_size];
79
80 ccdigest(di, [self.escrowSigningPublicKey length], [self.escrowSigningPublicKey bytes], [result mutableBytes]);
81
82 return [result base64EncodedStringWithOptions:0];
83 }
84
85 // Verify signatures, or return nil
86 - (nullable instancetype) initWithBottledPeer:(OTBottledPeer*)bp
87 signatureUsingEscrow:(NSData*)signatureUsingEscrow
88 signatureUsingPeerKey:(NSData*)signatureUsingPeerKey
89 escrowedSigningPubKey:(SFECPublicKey *)escrowedSigningPubKey
90 error:(NSError**)error
91 {
92 self = [super init];
93 if (self) {
94 _bp = bp;
95 _escrowSigningSPKI = [escrowedSigningPubKey asSPKI];
96 _signatureUsingPeerKey = signatureUsingPeerKey;
97 _signatureUsingEscrowKey = signatureUsingEscrow;
98 _escrowSigningPublicKey = [escrowedSigningPubKey keyData];
99
100 SFEC_X962SigningOperation* xso = [OTBottledPeerSigned signingOperation];
101
102 SFSignedData *escrowSigned = [[SFSignedData alloc] initWithData:bp.data signature:signatureUsingEscrow];
103 if (![xso verify:escrowSigned withKey:escrowedSigningPubKey error:error]) {
104 return nil;
105 }
106 SFSignedData *peerSigned = [[SFSignedData alloc] initWithData:bp.data signature:signatureUsingPeerKey];
107 if (![xso verify:peerSigned withKey:bp.peerSigningKey.publicKey error:error]) {
108 return nil;
109 }
110 //stuff restored keys in the keychain
111 [OTIdentity storeOctagonIdentityIntoKeychain:self.bp.peerSigningKey restoredEncryptionKey:self.bp.peerEncryptionKey escrowSigningPubKeyHash:self.escrowSigningPublicKeyHash restoredPeerID:self.bp.spID error:error];
112 }
113 return self;
114 }
115
116 + (SFEC_X962SigningOperation*) signingOperation
117 {
118 SFECKeySpecifier *keySpecifier = [[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384];
119 id<SFDigestOperation> digestOperation = [[SFSHA384DigestOperation alloc] init];
120 return [[SFEC_X962SigningOperation alloc] initWithKeySpecifier:keySpecifier digestOperation:digestOperation];
121 }
122
123 + (BOOL) verifyBottleSignature:(NSData*)data signature:(NSData*)signature key:(_SFECPublicKey*) pubKey error:(NSError**)error
124 {
125 SFEC_X962SigningOperation* xso = [OTBottledPeerSigned signingOperation];
126
127 SFSignedData *peerSigned = [[SFSignedData alloc] initWithData:data signature:signature];
128
129 return ([xso verify:peerSigned withKey:pubKey error:error] != nil);
130
131 }
132
133 - (nullable instancetype) initWithBottledPeerRecord:(OTBottledPeerRecord *)record
134 escrowKeys:(OTEscrowKeys *)escrowKeys
135 error:(NSError**)error
136 {
137 OTBottledPeer *bp = [[OTBottledPeer alloc] initWithData:record.bottle
138 escrowKeys:escrowKeys
139 error:error];
140 if (!bp) {
141 return nil;
142 }
143 return [self initWithBottledPeer:bp
144 signatureUsingEscrow:record.signatureUsingEscrowKey
145 signatureUsingPeerKey:record.signatureUsingPeerKey
146 escrowedSigningPubKey:escrowKeys.signingKey.publicKey
147 error:error];
148 }
149
150 - (OTBottledPeerRecord *)asRecord:(NSString*)escrowRecordID
151 {
152 OTBottledPeerRecord *rec = [[OTBottledPeerRecord alloc] init];
153 rec.spID = self.bp.spID;
154 rec.escrowRecordID = [escrowRecordID copy];
155 rec.peerSigningSPKI = [self.bp.peerSigningKey.publicKey asSPKI];
156 rec.escrowedSigningSPKI = self.escrowSigningSPKI;
157 rec.bottle = self.bp.data;
158 rec.signatureUsingPeerKey = self.signatureUsingPeerKey;
159 rec.signatureUsingEscrowKey = self.signatureUsingEscrowKey;
160 rec.launched = @"NO";
161 return rec;
162 }
163
164 @end
165 #endif
166