OLMKit: SAS: Add PK signing

(cherry picked from commit ff31d489c68d5d9e597bd55a6f6a64f3fe4c7ecc)
poljar/cmake_sas
manuroe 2019-04-10 23:15:27 +02:00
parent 4057f59453
commit 809793c9ba
4 changed files with 208 additions and 0 deletions

View File

@ -28,6 +28,7 @@
#import <OLMKit/OLMOutboundGroupSession.h>
#import <OLMKit/OLMPkEncryption.h>
#import <OLMKit/OLMPkDecryption.h>
#import <OLMKit/OLMPkSigning.h>
#import <OLMKit/OLMSAS.h>
@interface OLMKit : NSObject

View File

@ -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

123
xcode/OLMKit/OLMPkSigning.m Normal file
View File

@ -0,0 +1,123 @@
/*
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;
}
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

View File

@ -104,4 +104,39 @@
XCTAssertEqualObjects(decrypted, TEST_TEXT);
}
- (void)testSignAndVerify {
UInt8 seedBytes[] = {
0x77, 0x07, 0x6D, 0x0A, 0x73, 0x18, 0xA5, 0x7D,
0x3C, 0x16, 0xC1, 0x72, 0x51, 0xB2, 0x66, 0x45,
0xDF, 0x4C, 0x2F, 0x87, 0xEB, 0xC0, 0x99, 0x2A,
0xB1, 0x77, 0xFB, 0xA5, 0x1D, 0xB9, 0x2C, 0x2A
};
NSData *seed = [NSData dataWithBytes:seedBytes length:sizeof(seedBytes)];
NSString *TEST_TEXT = @"We hold these truths to be self-evident, that all men are created equal, that they are endowed by their Creator with certain unalienable Rights, that among these are Life, Liberty and the pursuit of Happiness.";
OLMPkSigning *signing = [OLMPkSigning new];
NSError *error;
NSString *pubKey = [signing doInitWithSeed:seed error:&error];
XCTAssertNotNil(pubKey);
XCTAssertNil(error);
NSString *sig = [signing sign:TEST_TEXT error:&error];
XCTAssertNotNil(sig);
XCTAssertNil(error);
OLMUtility *util = [OLMUtility new];
BOOL verify = [util verifyEd25519Signature:sig key:pubKey message:[TEST_TEXT dataUsingEncoding:NSUTF8StringEncoding] error:&error];
XCTAssertTrue(verify);
XCTAssertNil(error);
NSString *badSig = [sig stringByReplacingCharactersInRange:NSMakeRange(0, 1) withString:@"p"];
verify = [util verifyEd25519Signature:badSig key:pubKey message:[TEST_TEXT dataUsingEncoding:NSUTF8StringEncoding] error:&error];
XCTAssertFalse(verify);
XCTAssertNotNil(error);
}
@end