diff options
Diffstat (limited to 'xcode/OLMKit')
-rw-r--r-- | xcode/OLMKit/OLMKit.h | 2 | ||||
-rw-r--r-- | xcode/OLMKit/OLMPkEncryption.m | 4 | ||||
-rw-r--r-- | xcode/OLMKit/OLMPkSigning.h | 49 | ||||
-rw-r--r-- | xcode/OLMKit/OLMPkSigning.m | 125 | ||||
-rw-r--r-- | xcode/OLMKit/OLMSAS.h | 70 | ||||
-rw-r--r-- | xcode/OLMKit/OLMSAS.m | 174 |
6 files changed, 422 insertions, 2 deletions
diff --git a/xcode/OLMKit/OLMKit.h b/xcode/OLMKit/OLMKit.h index 6f79399..54496a0 100644 --- a/xcode/OLMKit/OLMKit.h +++ b/xcode/OLMKit/OLMKit.h @@ -28,6 +28,8 @@ #import <OLMKit/OLMOutboundGroupSession.h> #import <OLMKit/OLMPkEncryption.h> #import <OLMKit/OLMPkDecryption.h> +#import <OLMKit/OLMPkSigning.h> +#import <OLMKit/OLMSAS.h> @interface OLMKit : NSObject diff --git a/xcode/OLMKit/OLMPkEncryption.m b/xcode/OLMKit/OLMPkEncryption.m index c2e3d04..34ad57c 100644 --- a/xcode/OLMKit/OLMPkEncryption.m +++ b/xcode/OLMKit/OLMPkEncryption.m @@ -65,13 +65,13 @@ size_t macLength = olm_pk_mac_length(session); NSMutableData *macData = [NSMutableData dataWithLength:macLength]; - if (!ciphertext) { + if (!macData) { return nil; } size_t ephemeralKeyLength = olm_pk_key_length(); NSMutableData *ephemeralKeyData = [NSMutableData dataWithLength:ephemeralKeyLength]; - if (!ciphertext) { + if (!ephemeralKeyData) { return nil; } diff --git a/xcode/OLMKit/OLMPkSigning.h b/xcode/OLMKit/OLMPkSigning.h new file mode 100644 index 0000000..09724e1 --- /dev/null +++ b/xcode/OLMKit/OLMPkSigning.h @@ -0,0 +1,49 @@ +/* + Copyright 2019 New Vector Ltd + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +#import <Foundation/Foundation.h> + +NS_ASSUME_NONNULL_BEGIN + +@interface OLMPkSigning : NSObject + +/** + Initialise the signing object with a public/private keypair from a seed. + + @param seed the seed. + @param error the error if any. + @return the public key + */ +- (NSString *)doInitWithSeed:(NSData*)seed error:(NSError* _Nullable *)error; + +/** + Sign a message. + + @param message the message to sign. + @param error the error if any. + @return the signature. + */ +- (NSString *)sign:(NSString*)message error:(NSError* _Nullable *)error; + +/** + Generate a seed. + + @return the generated seed. + */ ++ (NSData *)generateSeed; + +@end + +NS_ASSUME_NONNULL_END diff --git a/xcode/OLMKit/OLMPkSigning.m b/xcode/OLMKit/OLMPkSigning.m new file mode 100644 index 0000000..d5c7d09 --- /dev/null +++ b/xcode/OLMKit/OLMPkSigning.m @@ -0,0 +1,125 @@ +/* + Copyright 2019 New Vector Ltd + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +#import "OLMPkSigning.h" + +#include "olm/olm.h" +#include "olm/pk.h" +#include "OLMUtility.h" + +@interface OLMPkSigning () +{ + OlmPkSigning *sign; +} +@end + +@implementation OLMPkSigning + +- (void)dealloc { + olm_clear_pk_signing(sign); + free(sign); +} + + +- (instancetype)init { + self = [super init]; + if (self) { + sign = (OlmPkSigning *)malloc(olm_pk_signing_size()); + olm_pk_signing(sign); + } + return self; +} + +- (NSString *)doInitWithSeed:(NSData *)seed error:(NSError *__autoreleasing _Nullable *)error { + size_t publicKeyLength = olm_pk_signing_public_key_length(); + NSMutableData *publicKeyData = [NSMutableData dataWithLength:publicKeyLength]; + if (!publicKeyData) { + return nil; + } + + NSMutableData *mutableSeed = [NSMutableData dataWithData:seed]; + + size_t result = olm_pk_signing_key_from_seed(sign, + publicKeyData.mutableBytes, publicKeyLength, + mutableSeed.mutableBytes, mutableSeed.length); + if (result == olm_error()) { + const char *olm_error = olm_pk_signing_last_error(sign); + + NSString *errorString = [NSString stringWithUTF8String:olm_error]; + NSLog(@"[OLMPkSigning] doInitWithSeed: olm_pk_signing_key_from_seed error: %@", errorString); + + if (error && olm_error && errorString) { + *error = [NSError errorWithDomain:OLMErrorDomain + code:0 + userInfo:@{ + NSLocalizedDescriptionKey: errorString, + NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:@"olm_pk_signing_key_from_seed error: %@", errorString] + }]; + } + + return nil; + } + + [mutableSeed resetBytesInRange:NSMakeRange(0, mutableSeed.length)]; + + NSString *publicKey = [[NSString alloc] initWithData:publicKeyData encoding:NSUTF8StringEncoding]; + return publicKey; +} + +- (NSString *)sign:(NSString *)message error:(NSError *__autoreleasing _Nullable *)error { + NSData *messageData = [message dataUsingEncoding:NSUTF8StringEncoding]; + + size_t signatureLength = olm_pk_signature_length(); + NSMutableData *signatureData = [NSMutableData dataWithLength:signatureLength]; + if (!signatureData) { + return nil; + } + + size_t result = olm_pk_sign(sign, + messageData.bytes, messageData.length, + signatureData.mutableBytes, signatureLength); + if (result == olm_error()) { + const char *olm_error = olm_pk_signing_last_error(sign); + + NSString *errorString = [NSString stringWithUTF8String:olm_error]; + NSLog(@"[OLMPkSigning] sign: olm_pk_sign error: %@", errorString); + + if (error && olm_error && errorString) { + *error = [NSError errorWithDomain:OLMErrorDomain + code:0 + userInfo:@{ + NSLocalizedDescriptionKey: errorString, + NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:@"olm_pk_sign error: %@", errorString] + }]; + } + + return nil; + } + + NSString *signature = [[NSString alloc] initWithData:signatureData encoding:NSUTF8StringEncoding]; + return signature; +} + ++ (NSData *)generateSeed { + size_t seedLength = olm_pk_signing_seed_length(); + NSMutableData *seed = [OLMUtility randomBytesOfLength:seedLength]; + if (!seed) { + return nil; + } + + return seed; +} + +@end diff --git a/xcode/OLMKit/OLMSAS.h b/xcode/OLMKit/OLMSAS.h new file mode 100644 index 0000000..3785b03 --- /dev/null +++ b/xcode/OLMKit/OLMSAS.h @@ -0,0 +1,70 @@ +/* + Copyright 2019 New Vector Ltd + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +#import <Foundation/Foundation.h> + +NS_ASSUME_NONNULL_BEGIN + +/** + Short Authentication String verification utility class. + */ +@interface OLMSAS : NSObject + +/** + Get the public key of the SAS object. + */ +- (NSString * _Nullable)publicKey; + +/** + Set the public key of other user. + + @param theirPublicKey the other user's public key. + @return error the error if any. + */ +- (NSError* _Nullable)setTheirPublicKey:(NSString*)theirPublicKey; + +/** + Generate bytes to use for the short authentication string. + + @param info extra information to mix in when generating the bytes, as per the Matrix spec. + @param length the size of the output buffer. For hex-based SAS as in the Matrix spec, this will be 5. + @return generated bytes + */ +- (NSData *)generateBytes:(NSString*)info length:(NSUInteger)length; + +/** + Generate a message authentication code (MAC) based on the shared secret. + + @param input the message to produce the authentication code for. + @param info extra information to mix in when generating the MAC, as per the Matrix spec. + @param error the error if any. + @return the MAC. + */ +- (NSString *)calculateMac:(NSString*)input info:(NSString*)info error:(NSError* _Nullable *)error; + +/** + Generate a message authentication code (MAC) based on the shared secret. + For compatibility with an old version of olm.js. + + @param input the message to produce the authentication code for. + @param info extra information to mix in when generating the MAC, as per the Matrix spec. + @param error the error if any. + @return the MAC. + */ +- (NSString *)calculateMacLongKdf:(NSString*)input info:(NSString*)info error:(NSError* _Nullable *)error; + +@end + +NS_ASSUME_NONNULL_END diff --git a/xcode/OLMKit/OLMSAS.m b/xcode/OLMKit/OLMSAS.m new file mode 100644 index 0000000..fed370b --- /dev/null +++ b/xcode/OLMKit/OLMSAS.m @@ -0,0 +1,174 @@ +/* + Copyright 2018 New Vector Ltd + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +#import "OLMSAS.h" + +#include "olm/olm.h" +#include "olm/sas.h" +#include "OLMUtility.h" + +@interface OLMSAS () { + void *olmSASbuffer; + OlmSAS *olmSAS; +} +@end + +@implementation OLMSAS + +- (void)dealloc { + olm_clear_sas(olmSAS); + free(olmSASbuffer); +} + +- (instancetype)init { + self = [super init]; + if (self) { + olmSASbuffer = malloc(olm_sas_size()); + olmSAS = olm_sas(olmSASbuffer); + + size_t randomLength = olm_create_sas_random_length(olmSAS); + NSMutableData *random = [OLMUtility randomBytesOfLength:randomLength]; + if (!random) { + return nil; + } + + olm_create_sas(olmSAS, random.mutableBytes, randomLength); + + [random resetBytesInRange:NSMakeRange(0, randomLength)]; + } + return self; +} + +- (NSString * _Nullable)publicKey { + size_t publicKeyLength = olm_sas_pubkey_length(olmSAS); + NSMutableData *publicKeyData = [NSMutableData dataWithLength:publicKeyLength]; + if (!publicKeyData) { + return nil; + } + + size_t result = olm_sas_get_pubkey(olmSAS, publicKeyData.mutableBytes, publicKeyLength); + if (result == olm_error()) { + const char *olm_error = olm_sas_last_error(olmSAS); + NSLog(@"[OLMSAS] publicKey: olm_sas_get_pubkey error: %s", olm_error); + return nil; + } + + NSString *publicKey = [[NSString alloc] initWithData:publicKeyData encoding:NSUTF8StringEncoding]; + return publicKey; +} + +- (NSError * _Nullable)setTheirPublicKey:(NSString*)theirPublicKey { + NSMutableData *theirPublicKeyData = [theirPublicKey dataUsingEncoding:NSUTF8StringEncoding].mutableCopy; + + size_t result = olm_sas_set_their_key(olmSAS, theirPublicKeyData.mutableBytes, theirPublicKeyData.length); + if (result == olm_error()) { + const char *olm_error = olm_sas_last_error(olmSAS); + NSLog(@"[OLMSAS] setTheirPublicKey: olm_sas_set_their_key error: %s", olm_error); + + NSString *errorString = [NSString stringWithUTF8String:olm_error]; + if (olm_error && errorString) { + return [NSError errorWithDomain:OLMErrorDomain + code:0 + userInfo:@{ + NSLocalizedDescriptionKey: errorString, + NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:@"olm_sas_set_their_key error: %@", errorString] + }]; + } + } + + return nil; +} + +- (NSData *)generateBytes:(NSString *)info length:(NSUInteger)length { + NSData *infoData = [info dataUsingEncoding:NSUTF8StringEncoding]; + + NSMutableData *bytes = [NSMutableData dataWithLength:length]; + if (!bytes) { + return nil; + } + + olm_sas_generate_bytes(olmSAS, infoData.bytes, infoData.length, bytes.mutableBytes, length); + return bytes; +} + +- (NSString *)calculateMac:(NSString *)input info:(NSString *)info error:(NSError *__autoreleasing _Nullable *)error { + NSMutableData *inputData = [input dataUsingEncoding:NSUTF8StringEncoding].mutableCopy; + NSData *infoData = [info dataUsingEncoding:NSUTF8StringEncoding]; + + size_t macLength = olm_sas_mac_length(olmSAS); + NSMutableData *macData = [NSMutableData dataWithLength:macLength]; + if (!macData) { + return nil; + } + + size_t result = olm_sas_calculate_mac(olmSAS, + inputData.mutableBytes, inputData.length, + infoData.bytes, infoData.length, + macData.mutableBytes, macLength); + if (result == olm_error()) { + const char *olm_error = olm_sas_last_error(olmSAS); + NSLog(@"[OLMSAS] calculateMac: olm_sas_calculate_mac error: %s", olm_error); + + NSString *errorString = [NSString stringWithUTF8String:olm_error]; + if (error && olm_error && errorString) { + *error = [NSError errorWithDomain:OLMErrorDomain + code:0 + userInfo:@{ + NSLocalizedDescriptionKey: errorString, + NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:@"olm_sas_calculate_mac error: %@", errorString] + }]; + } + return nil; + } + + NSString *mac = [[NSString alloc] initWithData:macData encoding:NSUTF8StringEncoding]; + return mac; +} + +- (NSString *)calculateMacLongKdf:(NSString *)input info:(NSString *)info error:(NSError *__autoreleasing _Nullable *)error { + NSMutableData *inputData = [input dataUsingEncoding:NSUTF8StringEncoding].mutableCopy; + NSData *infoData = [info dataUsingEncoding:NSUTF8StringEncoding]; + + size_t macLength = olm_sas_mac_length(olmSAS); + NSMutableData *macData = [NSMutableData dataWithLength:macLength]; + if (!macData) { + return nil; + } + + size_t result = olm_sas_calculate_mac_long_kdf(olmSAS, + inputData.mutableBytes, inputData.length, + infoData.bytes, infoData.length, + macData.mutableBytes, macLength); + if (result == olm_error()) { + const char *olm_error = olm_sas_last_error(olmSAS); + NSLog(@"[OLMSAS] calculateMacLongKdf: olm_sas_calculate_mac error: %s", olm_error); + + NSString *errorString = [NSString stringWithUTF8String:olm_error]; + if (error && olm_error && errorString) { + *error = [NSError errorWithDomain:OLMErrorDomain + code:0 + userInfo:@{ + NSLocalizedDescriptionKey: errorString, + NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:@"olm_sas_calculate_mac_long_kdf error: %@", errorString] + }]; + } + return nil; + } + + NSString *mac = [[NSString alloc] initWithData:macData encoding:NSUTF8StringEncoding]; + return mac; +} + +@end |