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