diff --git a/objc/BUILD b/objc/BUILD index c0933e59eb..ae39116958 100644 --- a/objc/BUILD +++ b/objc/BUILD @@ -44,7 +44,11 @@ objc_library( ], visibility = ["//visibility:public"], deps = [ + ":aead", + ":keyset_reader", "//cc:keyset_handle", + "//cc/util:status", + "//objc/util:errors", "//objc/util:strings", "//proto:all_objc_proto", "@com_google_absl//absl/strings", @@ -85,9 +89,14 @@ objc_library( objc_library( name = "keyset_reader", - hdrs = ["TINKKeysetReader.h"], + srcs = ["core/TINKKeysetReader.mm"], + hdrs = [ + "TINKKeysetReader.h", + "core/TINKKeysetReader_Internal.h", + ], visibility = ["//visibility:public"], deps = [ + "//cc:keyset_reader", "//proto:all_objc_proto", ], ) @@ -132,7 +141,9 @@ objc_library( "Tests/UnitTests/**/*.h", ]), deps = [ + ":aead", ":binary_keyset_reader", + ":keyset_handle", "//cc/util:test_util", "//objc/util:strings", "//proto:all_objc_proto", diff --git a/objc/TINKBinaryKeysetReader.h b/objc/TINKBinaryKeysetReader.h index efc41bf40b..5676624165 100644 --- a/objc/TINKBinaryKeysetReader.h +++ b/objc/TINKBinaryKeysetReader.h @@ -23,7 +23,7 @@ NS_ASSUME_NONNULL_BEGIN -@interface TINKBinaryKeysetReader : NSObject +@interface TINKBinaryKeysetReader : TINKKeysetReader - (nullable instancetype)init NS_UNAVAILABLE; diff --git a/objc/TINKKeysetHandle.h b/objc/TINKKeysetHandle.h index 8212db0158..8336a80e85 100644 --- a/objc/TINKKeysetHandle.h +++ b/objc/TINKKeysetHandle.h @@ -18,7 +18,9 @@ #import -@class TINKPBKeyset; +#import "objc/TINKAead.h" +#import "objc/TINKKeysetReader.h" +#import "proto/Tink.pbobjc.h" NS_ASSUME_NONNULL_BEGIN @@ -28,18 +30,35 @@ NS_ASSUME_NONNULL_BEGIN */ @interface TINKKeysetHandle : NSObject -@property(nonatomic, readonly) TINKPBKeyset *keyset; - -/** Use initWithKeyset: to get an instance of TINKKeysetHandle. */ +/** + * Use -initWithKeysetReader:andKey:error: or -initWithTemplate:error: to get an instance of + * TINKKeysetHandle. + */ - (nullable instancetype)init NS_UNAVAILABLE; /** - * Designated initializer. + * Creates a TINKKeysetHandle from an encrypted keyset obtained via @c reader using @c aeadKey to + * decrypt the keyset. + * + * @param reader An instance of TINKKeysetReader. + * @param aeadKey An instance of TINKAead that's used to decrypt the keyset. + * @param error If non-nil it will be populated with a descriptive error message. + * @return A TINKKeysetHandle, or nil in case of error. + */ +- (nullable instancetype)initWithKeysetReader:(TINKKeysetReader *)reader + andKey:(TINKAead *)aeadKey + error:(NSError **)error; + +/** + * Returns a new TINKKeysetHandle that contains a single fresh key generated according to + * @c keyTemplate. * - * @param keyset An instance of TINKPBKeyset protocol buffer. - * @return An instance of TINKKeysetHandle or nil in case of error. + * @param keyTemplate A TINKPBKeyTemplate protocol buffer that describes the key to be generated. + * @param error If non-nil it will be populated with a descriptive error message. + * @return A TINKKeysetHandle, or nil in case of error. */ -- (nullable instancetype)initWithKeyset:(TINKPBKeyset *)keyset NS_DESIGNATED_INITIALIZER; +- (nullable instancetype)initWithKeyTemplate:(TINKPBKeyTemplate *)keyTemplate + error:(NSError **)error; @end diff --git a/objc/TINKKeysetReader.h b/objc/TINKKeysetReader.h index a5f2afe45e..bb8111b6c3 100644 --- a/objc/TINKKeysetReader.h +++ b/objc/TINKKeysetReader.h @@ -23,9 +23,9 @@ NS_ASSUME_NONNULL_BEGIN /** - * The protocol for keyset readers. + * Parent class for keyset readers. */ -@protocol TINKKeysetReader +@interface TINKKeysetReader : NSObject /* Reads a Keyset. Returns nil in case of error and sets error to a descriptive value. */ - (nullable TINKPBKeyset *)readWithError:(NSError **)error; diff --git a/objc/Tests/UnitTests/core/TINKKeysetHandleTest.mm b/objc/Tests/UnitTests/core/TINKKeysetHandleTest.mm new file mode 100644 index 0000000000..a9a80385de --- /dev/null +++ b/objc/Tests/UnitTests/core/TINKKeysetHandleTest.mm @@ -0,0 +1,154 @@ +/** + * Copyright 2017 Google Inc. + * + * 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 "objc/TINKKeysetHandle.h" +#import "objc/core/TINKKeysetHandle_Internal.h" + +#import + +#import "objc/TINKAead.h" +#import "objc/TINKAead_Internal.h" +#import "objc/TINKBinaryKeysetReader.h" +#import "objc/util/TINKStrings.h" +#import "proto/Tink.pbobjc.h" + +#include "cc/util/test_util.h" +#include "proto/tink.pb.h" + +static TINKPBKeyset *gKeyset; + +@interface TINKKeysetHandleTest : XCTestCase +@end + +@implementation TINKKeysetHandleTest + ++ (void)setUp { + google::crypto::tink::Keyset ccKeyset; + google::crypto::tink::Keyset::Key ccKey; + + crypto::tink::test::AddTinkKey("some key type", 42, ccKey, + google::crypto::tink::KeyStatusType::ENABLED, + google::crypto::tink::KeyData::SYMMETRIC, &ccKeyset); + crypto::tink::test::AddRawKey("some other key type", 711, ccKey, + google::crypto::tink::KeyStatusType::ENABLED, + google::crypto::tink::KeyData::SYMMETRIC, &ccKeyset); + ccKeyset.set_primary_key_id(42); + + std::string serializedKeyset = ccKeyset.SerializeAsString(); + + NSError *error = nil; + gKeyset = [TINKPBKeyset + parseFromData:[NSData dataWithBytes:serializedKeyset.data() length:serializedKeyset.length()] + error:&error]; + XCTAssertNotNil(gKeyset); + XCTAssertNil(error); +} + +- (void)testGoodEncryptedKeyset_Binary { + crypto::tink::test::DummyAead *ccAead = new crypto::tink::test::DummyAead("dummy aead 42"); + TINKAead *aead = [[TINKAead alloc] initWithPrimitive:ccAead]; + + NSData *keysetCiphertext = [aead encrypt:gKeyset.data withAdditionalData:[NSData data] error:nil]; + + XCTAssertNotNil(keysetCiphertext); + + TINKPBEncryptedKeyset *encryptedKeyset = [[TINKPBEncryptedKeyset alloc] init]; + encryptedKeyset.encryptedKeyset = keysetCiphertext; + + TINKBinaryKeysetReader *reader = + [[TINKBinaryKeysetReader alloc] initWithSerializedKeyset:encryptedKeyset.data error:nil]; + + TINKKeysetHandle *handle = + [[TINKKeysetHandle alloc] initWithKeysetReader:reader andKey:aead error:nil]; + XCTAssertNotNil(handle); + std::string output; + handle.ccKeysetHandle->get_keyset().SerializeToString(&output); + + XCTAssertTrue( + [gKeyset.data isEqualToData:[NSData dataWithBytes:output.data() length:output.size()]]); +} + +- (void)testWrongAead_Binary { + crypto::tink::test::DummyAead *ccAead = new crypto::tink::test::DummyAead("dummy aead 42"); + TINKAead *aead = [[TINKAead alloc] initWithPrimitive:ccAead]; + + NSData *keysetCiphertext = [aead encrypt:gKeyset.data withAdditionalData:[NSData data] error:nil]; + + TINKPBEncryptedKeyset *encryptedKeyset = [[TINKPBEncryptedKeyset alloc] init]; + encryptedKeyset.encryptedKeyset = keysetCiphertext; + + TINKBinaryKeysetReader *reader = + [[TINKBinaryKeysetReader alloc] initWithSerializedKeyset:encryptedKeyset.data error:nil]; + + crypto::tink::test::DummyAead *ccWrongAead = new crypto::tink::test::DummyAead("wrong aead"); + TINKAead *wrongAead = [[TINKAead alloc] initWithPrimitive:ccWrongAead]; + + NSError *error = nil; + TINKKeysetHandle *handle = + [[TINKKeysetHandle alloc] initWithKeysetReader:reader andKey:wrongAead error:&error]; + XCTAssertNil(handle); + XCTAssertEqual(error.code, crypto::tink::util::error::INVALID_ARGUMENT); +} + +- (void)testNoKeysetInCiphertext_Binary { + crypto::tink::test::DummyAead *ccAead = new crypto::tink::test::DummyAead("dummy aead 42"); + TINKAead *aead = [[TINKAead alloc] initWithPrimitive:ccAead]; + NSData *keysetCiphertext = + [aead encrypt:[@"not a serialized keyset" dataUsingEncoding:NSUTF8StringEncoding] + withAdditionalData:[NSData data] + error:nil]; + + TINKBinaryKeysetReader *reader = + [[TINKBinaryKeysetReader alloc] initWithSerializedKeyset:keysetCiphertext error:nil]; + + NSError *error = nil; + TINKKeysetHandle *handle = + [[TINKKeysetHandle alloc] initWithKeysetReader:reader andKey:aead error:&error]; + XCTAssertNil(handle); + XCTAssertEqual(error.code, crypto::tink::util::error::INVALID_ARGUMENT); +} + +- (void)testWrongCiphertext_Binary { + crypto::tink::test::DummyAead *ccAead = new crypto::tink::test::DummyAead("dummy aead 42"); + TINKAead *aead = [[TINKAead alloc] initWithPrimitive:ccAead]; + NSString *keysetCiphertext = @"totally wrong ciphertext"; + + TINKPBEncryptedKeyset *encryptedKeyset = [[TINKPBEncryptedKeyset alloc] init]; + encryptedKeyset.encryptedKeyset = [keysetCiphertext dataUsingEncoding:NSUTF8StringEncoding]; + + TINKBinaryKeysetReader *reader = + [[TINKBinaryKeysetReader alloc] initWithSerializedKeyset:encryptedKeyset.data error:nil]; + NSError *error = nil; + TINKKeysetHandle *handle = + [[TINKKeysetHandle alloc] initWithKeysetReader:reader andKey:aead error:&error]; + XCTAssertNil(handle); + XCTAssertEqual(error.code, crypto::tink::util::error::INVALID_ARGUMENT); +} + +- (void)testInvalidKeyTemplate { + NSError *error = nil; + TINKKeysetHandle *handle = [[TINKKeysetHandle alloc] initWithKeyTemplate:nil error:&error]; + XCTAssertNil(handle); + XCTAssertEqual(error.code, crypto::tink::util::error::INVALID_ARGUMENT); +} + +- (void)testValidKeyTeamplte { + // TODO(candrian): Implement this once the C++ method is working. +} + +@end diff --git a/objc/aead/BUILD b/objc/aead/BUILD index f8fe12ed6d..fc7ea8234c 100644 --- a/objc/aead/BUILD +++ b/objc/aead/BUILD @@ -13,6 +13,7 @@ objc_library( "//objc:aead", "//objc:keyset_handle", "//objc/util:errors", + "//proto:all_objc_proto", "@com_google_absl//absl/strings", ], ) diff --git a/objc/core/TINKBinaryKeysetReader.mm b/objc/core/TINKBinaryKeysetReader.mm index b6eb7a5149..46c0088e97 100644 --- a/objc/core/TINKBinaryKeysetReader.mm +++ b/objc/core/TINKBinaryKeysetReader.mm @@ -17,6 +17,9 @@ */ #import "objc/TINKBinaryKeysetReader.h" + +#import "objc/TINKKeysetReader.h" +#import "objc/core/TINKKeysetReader_Internal.h" #import "objc/util/TINKErrors.h" #import "objc/util/TINKStrings.h" #import "proto/Tink.pbobjc.h" @@ -25,9 +28,7 @@ #include "cc/binary_keyset_reader.h" #include "proto/tink.pb.h" -@implementation TINKBinaryKeysetReader { - std::unique_ptr _ccReader; -} +@implementation TINKBinaryKeysetReader - (instancetype)initWithSerializedKeyset:(NSData *)keyset error:(NSError **)error { if (keyset == nil) { @@ -47,17 +48,13 @@ - (instancetype)initWithSerializedKeyset:(NSData *)keyset error:(NSError **)erro } return nil; } - _ccReader = std::move(st.ValueOrDie()); + self.ccReader = std::move(st.ValueOrDie()); } return self; } -- (void)dealloc { - _ccReader.reset(); -} - - (TINKPBKeyset *)readWithError:(NSError **)error { - auto st = _ccReader->Read(); + auto st = self.ccReader->Read(); if (!st.ok()) { if (error) { *error = TINKStatusToError(st.status()); @@ -89,7 +86,7 @@ - (TINKPBKeyset *)readWithError:(NSError **)error { } - (TINKPBEncryptedKeyset *)readEncryptedWithError:(NSError **)error { - auto st = _ccReader->ReadEncrypted(); + auto st = self.ccReader->ReadEncrypted(); if (!st.ok()) { if (error) { *error = TINKStatusToError(st.status()); diff --git a/objc/core/TINKKeysetHandle.mm b/objc/core/TINKKeysetHandle.mm index 0eec9b0c7d..4e7caf782b 100644 --- a/objc/core/TINKKeysetHandle.mm +++ b/objc/core/TINKKeysetHandle.mm @@ -17,42 +17,87 @@ */ #import "objc/TINKKeysetHandle.h" -#import "objc/core/TINKKeysetHandle_Internal.h" #include "cc/keyset_handle.h" +#include "cc/util/status.h" #include "proto/tink.pb.h" +#import "objc/TINKAead.h" +#import "objc/TINKAead_Internal.h" +#import "objc/TINKKeysetReader.h" +#import "objc/core/TINKKeysetReader_Internal.h" +#import "objc/util/TINKErrors.h" #import "objc/util/TINKStrings.h" #import "proto/Tink.pbobjc.h" -@implementation TINKKeysetHandle +@implementation TINKKeysetHandle { + std::unique_ptr _ccKeysetHandle; +} -- (instancetype)initWithKeyset:(TINKPBKeyset *)keyset { +- (instancetype)initWithCCKeysetHandle:(std::unique_ptr)ccKeysetHandle { self = [super init]; if (self) { - // Serialize the Obj-C protocol buffer. - std::string serializedKeyset = TINKPBSerializeToString(keyset, nil); + _ccKeysetHandle = std::move(ccKeysetHandle); + } + return self; +} - // Deserialize it to a C++ protocol buffer. - _ccKeysetPB = new google::crypto::tink::Keyset(); - if (!_ccKeysetPB || !_ccKeysetPB->ParseFromString(serializedKeyset)) { +- (void)dealloc { + _ccKeysetHandle.reset(); +} + +- (nullable instancetype)initWithKeysetReader:(TINKKeysetReader *)reader + andKey:(TINKAead *)aeadKey + error:(NSError **)error { + crypto::tink::Aead *ccAead = aeadKey.primitive; + + // KeysetHandle::Read takes ownership of reader.ccReader. + auto st = crypto::tink::KeysetHandle::Read(std::move(reader.ccReader), *ccAead); + if (!st.ok()) { + if (error) { + *error = TINKStatusToError(st.status()); return nil; } + } - _ccKeysetHandle = new crypto::tink::KeysetHandle(*_ccKeysetPB); - if (!_ccKeysetHandle) { - delete _ccKeysetPB; - return nil; + return [self initWithCCKeysetHandle:std::move(st.ValueOrDie())]; +} + +- (nullable instancetype)initWithKeyTemplate:(TINKPBKeyTemplate *)keyTemplate + error:(NSError **)error { + // Serialize the Obj-C protocol buffer. + std::string serializedKeyTemplate = TINKPBSerializeToString(keyTemplate, error); + if (serializedKeyTemplate.empty()) { + return nil; + } + + // Deserialize it to a C++ protocol buffer. + google::crypto::tink::KeyTemplate ccKeyTemplate; + if (!ccKeyTemplate.ParseFromString(serializedKeyTemplate)) { + if (error) { + *error = TINKStatusToError(crypto::tink::util::Status( + crypto::tink::util::error::INVALID_ARGUMENT, "Could not parse keyTemplate.")); } + return nil; + } - _keyset = keyset; + auto st = crypto::tink::KeysetHandle::GenerateNew(ccKeyTemplate); + if (!st.ok()) { + if (error) { + *error = TINKStatusToError(st.status()); + } + return nil; } - return self; + + return [self initWithCCKeysetHandle:std::move(st.ValueOrDie())]; } -- (void)dealloc { - delete _ccKeysetHandle; - delete _ccKeysetPB; +- (crypto::tink::KeysetHandle *)ccKeysetHandle { + return _ccKeysetHandle.get(); +} + +- (void)setCcKeysetHandle:(std::unique_ptr)handle { + _ccKeysetHandle = std::move(handle); } @end diff --git a/objc/core/TINKKeysetHandle_Internal.h b/objc/core/TINKKeysetHandle_Internal.h index 7924c66f75..e33f9eae8e 100644 --- a/objc/core/TINKKeysetHandle_Internal.h +++ b/objc/core/TINKKeysetHandle_Internal.h @@ -19,11 +19,11 @@ #import "objc/TINKKeysetHandle.h" #include "cc/keyset_handle.h" -#include "proto/tink.pb.h" @interface TINKKeysetHandle () -@property(nonatomic, readonly, nonnull) google::crypto::tink::Keyset *ccKeysetPB; -@property(nonatomic, readonly, nonnull) crypto::tink::KeysetHandle *ccKeysetHandle; +- (instancetype)initWithCCKeysetHandle:(std::unique_ptr)ccKeysetHandle; +- (crypto::tink::KeysetHandle *)ccKeysetHandle; +- (void)setCcKeysetHandle:(std::unique_ptr)handle; @end diff --git a/objc/core/TINKKeysetReader.mm b/objc/core/TINKKeysetReader.mm new file mode 100644 index 0000000000..d55ad4e293 --- /dev/null +++ b/objc/core/TINKKeysetReader.mm @@ -0,0 +1,42 @@ +/** + * Copyright 2017 Google Inc. + * + * 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 + +#import "objc/TINKKeysetReader.h" +#import "objc/core/TINKKeysetReader_Internal.h" + +#include "cc/keyset_reader.h" + +@implementation TINKKeysetReader { + std::unique_ptr _ccReader; +} + +- (void)setCcReader:(std::unique_ptr)ccReader { + _ccReader = std::move(ccReader); +} + +- (std::unique_ptr)ccReader { + return std::move(_ccReader); +} + +- (void)dealloc { + _ccReader.reset(); +} + +@end diff --git a/objc/core/TINKKeysetReader_Internal.h b/objc/core/TINKKeysetReader_Internal.h new file mode 100644 index 0000000000..c360522c5c --- /dev/null +++ b/objc/core/TINKKeysetReader_Internal.h @@ -0,0 +1,28 @@ +/** + * Copyright 2017 Google Inc. + * + * 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 "objc/TINKKeysetReader.h" + +#include "cc/keyset_reader.h" + +@interface TINKKeysetReader () + +- (void)setCcReader:(std::unique_ptr)ccReader; +- (std::unique_ptr)ccReader; + +@end diff --git a/objc/hybrid/BUILD b/objc/hybrid/BUILD index 42d779642a..85fc368cfc 100644 --- a/objc/hybrid/BUILD +++ b/objc/hybrid/BUILD @@ -120,6 +120,7 @@ objc_library( ":hybrid_decrypt_factory", "//cc:crypto_format", "//cc/util:status", + "//cc/util:test_util", "//objc:hybrid_decrypt", "//objc:hybrid_encrypt", "//objc:keyset_handle", @@ -138,6 +139,7 @@ objc_library( ":hybrid_encrypt_config", ":hybrid_encrypt_factory", "//cc/util:status", + "//cc/util:test_util", "//objc:hybrid_encrypt", "//objc:keyset_handle", "//objc/util:strings", diff --git a/objc/hybrid/Tests/TINKHybridDecryptFactoryTest.mm b/objc/hybrid/Tests/TINKHybridDecryptFactoryTest.mm index 6aebaa9f72..1c0d7ef7ea 100644 --- a/objc/hybrid/Tests/TINKHybridDecryptFactoryTest.mm +++ b/objc/hybrid/Tests/TINKHybridDecryptFactoryTest.mm @@ -20,6 +20,7 @@ #include "cc/crypto_format.h" #include "cc/util/status.h" +#include "cc/util/test_util.h" #import "proto/EciesAeadHkdf.pbobjc.h" #import "proto/Tink.pbobjc.h" @@ -85,7 +86,7 @@ @interface TINKHybridDecryptFactoryTest : XCTestCase // Get the key prefix using the C++ CryptoFormat API. // TODO(candrian): Update this to use the Obj-C API when it is implemented. std::string output_prefix = - crypto::tink::CryptoFormat::get_output_prefix(keysetHandle.ccKeysetPB->key(keyIndex)) + crypto::tink::CryptoFormat::get_output_prefix(keysetHandle.ccKeysetHandle->get_keyset().key(keyIndex)) .ValueOrDie(); NSData *outputPrefix = TINKStringToNSData(output_prefix); [ciphertext appendData:outputPrefix]; @@ -98,8 +99,8 @@ @interface TINKHybridDecryptFactoryTest : XCTestCase @implementation TINKHybridDecryptFactoryTest - (void)testPrimitiveWithEmptyKeyset { - TINKPBKeyset *keyset = [[TINKPBKeyset alloc] init]; - TINKKeysetHandle *keysetHandle = [[TINKKeysetHandle alloc] initWithKeyset:keyset]; + google::crypto::tink::Keyset keyset; + TINKKeysetHandle *keysetHandle = [[TINKKeysetHandle alloc] initWithCCKeysetHandle:crypto::tink::test::GetKeysetHandle(keyset)]; XCTAssertNotNil(keysetHandle); NSError *error = nil; @@ -122,10 +123,15 @@ - (void)testPrimitiveWithKeyset { TINKPBEciesAeadHkdfPrivateKey *eciesKey2 = getNewEciesPrivateKey(); TINKPBEciesAeadHkdfPrivateKey *eciesKey3 = getNewEciesPrivateKey(); TINKPBKeyset *keyset = createTestKeyset(eciesKey1, eciesKey2, eciesKey3); - TINKKeysetHandle *keysetHandle = [[TINKKeysetHandle alloc] initWithKeyset:keyset]; + google::crypto::tink::Keyset ccKeyset; + NSError *error = nil; + std::string serializedKeyset = TINKPBSerializeToString(keyset, &error); + XCTAssertNil(error); + XCTAssertTrue(ccKeyset.ParseFromString(serializedKeyset)); + TINKKeysetHandle *keysetHandle = [[TINKKeysetHandle alloc] initWithCCKeysetHandle:crypto::tink::test::GetKeysetHandle(ccKeyset)]; // Get a HybridDecrypt primitive using the test Keyset. - NSError *error = nil; + error = nil; id hybridDecrypt = [TINKHybridDecryptFactory primitiveWithKeysetHandle:keysetHandle error:&error]; XCTAssertNotNil(hybridDecrypt); diff --git a/objc/hybrid/Tests/TINKHybridEncryptFactoryTest.mm b/objc/hybrid/Tests/TINKHybridEncryptFactoryTest.mm index 2ae82dab3f..7dda0243d3 100644 --- a/objc/hybrid/Tests/TINKHybridEncryptFactoryTest.mm +++ b/objc/hybrid/Tests/TINKHybridEncryptFactoryTest.mm @@ -19,6 +19,8 @@ #import #include "cc/util/status.h" +#include "cc/util/test_util.h" +#include "proto/tink.pb.h" #import "proto/Common.pbobjc.h" #import "proto/EciesAeadHkdf.pbobjc.h" @@ -26,6 +28,7 @@ #import "objc/TINKHybridEncrypt.h" #import "objc/TINKKeysetHandle.h" +#import "objc/core/TINKKeysetHandle_Internal.h" #import "objc/hybrid/TINKHybridEncryptConfig.h" #import "objc/hybrid/TINKHybridEncryptFactory.h" #import "objc/util/TINKStrings.h" @@ -44,8 +47,8 @@ @interface TINKHybridEncryptFactoryTest : XCTestCase @implementation TINKHybridEncryptFactoryTest - (void)testPrimitiveWithEmptyKeyset { - TINKPBKeyset *keyset = [[TINKPBKeyset alloc] init]; - TINKKeysetHandle *keysetHandle = [[TINKKeysetHandle alloc] initWithKeyset:keyset]; + google::crypto::tink::Keyset keyset; + TINKKeysetHandle *keysetHandle = [[TINKKeysetHandle alloc] initWithCCKeysetHandle:crypto::tink::test::GetKeysetHandle(keyset)]; NSError *error = nil; id primitive = @@ -82,12 +85,19 @@ - (void)testPrimitiveWithKeyset { // Initialize the registry. [TINKHybridEncryptConfig registerStandardKeyTypes]; + NSError *error = nil; + std::string serializedKeyset = TINKPBSerializeToString(keyset, &error); + XCTAssertNil(error); + + google::crypto::tink::Keyset ccKeyset; + XCTAssertTrue(ccKeyset.ParseFromString(serializedKeyset)); + // Create a KeysetHandle and use it with the factory. - TINKKeysetHandle *keysetHandle = [[TINKKeysetHandle alloc] initWithKeyset:keyset]; + TINKKeysetHandle *keysetHandle = [[TINKKeysetHandle alloc] initWithCCKeysetHandle:crypto::tink::test::GetKeysetHandle(ccKeyset)]; XCTAssertNotNil(keysetHandle); // Get a HybridEncrypt primitive. - NSError *error = nil; + error = nil; id primitive = [TINKHybridEncryptFactory primitiveWithKeysetHandle:keysetHandle error:&error]; XCTAssertNotNil(primitive); diff --git a/objc/util/TINKErrors.h b/objc/util/TINKErrors.h index 3b40e3a00c..39b4fa2dc5 100644 --- a/objc/util/TINKErrors.h +++ b/objc/util/TINKErrors.h @@ -22,3 +22,6 @@ /** Converts a C++ Status code to NSError. */ NSError* TINKStatusToError(const crypto::tink::util::Status& status); + +/** Creates an NSError given a Tink error code and a message. */ +NSError* TINKError(crypto::tink::util::error::Code code, NSString* message); diff --git a/objc/util/TINKErrors.mm b/objc/util/TINKErrors.mm index bc1fd815ff..9ded9ac592 100644 --- a/objc/util/TINKErrors.mm +++ b/objc/util/TINKErrors.mm @@ -29,3 +29,11 @@ }; return [NSError errorWithDomain:kTinkErrorDomain code:status.error_code() userInfo:userInfo]; } + +NSError *TINKError(crypto::tink::util::error::Code code, NSString *message) { + NSDictionary *userInfo = @{ + NSLocalizedDescriptionKey : NSLocalizedString(@"Tink Error", nil), + NSLocalizedFailureReasonErrorKey : NSLocalizedString(message, nil), + }; + return [NSError errorWithDomain:kTinkErrorDomain code:code userInfo:userInfo]; +}