1//
2// TORX25519KeyPair.m
3// Tor
4//
5// Created by Benjamin Erhart on 11.10.21.
6//
7
8#import "TORX25519KeyPair.h"
9#import "TORAuthKey.h"
10
11#if __has_include(<lib/malloc/malloc.h>)
12
13#import <lib/malloc/malloc.h>
14#import <lib/crypt_ops/crypto_curve25519.h>
15#import <lib/encoding/binascii.h>
16
17@implementation TORX25519KeyPair
18
19- (instancetype)init
20{
21 if ((self = [super init]))
22 {
23 curve25519_keypair_t *keypair = tor_malloc_zero(sizeof(curve25519_keypair_t));
24 curve25519_init();
25 curve25519_keypair_generate(keypair, 0);
26
27 _privateKey = [TORX25519KeyPair base32Encode:[
28 NSData dataWithBytes:keypair->seckey.secret_key
29 length:sizeof(keypair->seckey.secret_key)]];
30 _publicKey = [TORX25519KeyPair base32Encode:[
31 NSData dataWithBytes:keypair->pubkey.public_key
32 length:sizeof(keypair->pubkey.public_key)]];
33
34 tor_free(keypair);
35 }
36 return self;
37}
38
39+ (nullable NSString *)base32Encode:(NSData *)raw
40{
41 char dest[base32_encoded_size(raw.length)];
42 base32_encode(dest, sizeof(dest), raw.bytes, raw.length);
43 return [NSString stringWithUTF8String:dest];
44}
45
46+ (nullable NSData *)base32Decode:(NSString *)encoded
47{
48 const char *src = [encoded cStringUsingEncoding:kCFStringEncodingUTF8];
49 char dest[sizeof(src) * 5 / 8];
50 base32_decode(dest, sizeof(dest), src, sizeof(src));
51 return [NSData dataWithBytes:dest length:sizeof(dest)];
52}
53
54#else // Stub for builds without tor.xcframework binary
55
56@implementation TORX25519KeyPair
57
58- (instancetype)init { return [super init]; }
59
60+ (nullable NSString *)base32Encode:(NSData *)raw { return nil; }
61+ (nullable NSData *)base32Decode:(NSString *)encoded { return nil; }
62
63#endif // __has_include(<lib/malloc/malloc.h>)
64
65- (instancetype)initWithBase32PrivateKey:(NSString *)privateKey andPublicKey:(NSString *)publicKey
66{
67 if ((self = [super init])) {
68 _privateKey = privateKey;
69 _publicKey = publicKey;
70 }
71 return self;
72}
73
74- (instancetype)initWithPrivateKey:(NSData *)privateKey andPublicKey:(NSData *)publicKey
75{
76 if ((self = [super init])) {
77 _privateKey = [TORX25519KeyPair base32Encode:privateKey];
78 _publicKey = [TORX25519KeyPair base32Encode:publicKey];
79 }
80 return self;
81}
82
83- (nullable TORAuthKey *)getPrivateAuthKeyForDomain:(nonnull NSString *)domain
84{
85 if (domain.length < 1) return nil;
86 NSURLComponents *urlc = [NSURLComponents new];
87 urlc.scheme = @"http";
88 urlc.host = domain;
89 NSURL *url = urlc.URL;
90 if (!url) return nil;
91 return [self getPrivateAuthKeyForUrl:url];
92}
93
94- (nullable TORAuthKey *)getPrivateAuthKeyForUrl:(nonnull NSURL *)url
95{
96 NSString *privateKey = _privateKey;
97 if (!privateKey) return nil;
98 return [[TORAuthKey alloc] initPrivate:privateKey forDomain:url];
99}
100
101- (nullable TORAuthKey *)getPublicAuthKeyWithName:(nonnull NSString *)name
102{
103 NSString *publicKey = _publicKey;
104 if (!publicKey) return nil;
105 if (name.length < 1) return nil;
106 return [[TORAuthKey alloc] initPublic:publicKey withName:name];
107}
108
109@end