-
-
Notifications
You must be signed in to change notification settings - Fork 38
/
certificateidentity.d
97 lines (77 loc) · 3.45 KB
/
certificateidentity.d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
module sideload.certificateidentity;
import std.algorithm.searching;
import std.digest.sha;
import file = std.file;
import std.path;
import std.uni;
import slf4d;
import botan.constants;
version = X509;
import botan.cert.x509.certstor;
import botan.cert.x509.x509_crl;
import botan.cert.x509.x509self;
import botan.pubkey.algo.rsa;
import botan.rng.rng;
import constants;
import server.appleaccount;
import server.developersession;
import sideload.bundle;
class CertificateIdentity {
RandomNumberGenerator rng = void;
X509Certificate certificate = void;
RSAPrivateKey privateKey = void;
string keyFile;
this(X509Certificate certificate, RSAPrivateKey privateKey) {
rng = RandomNumberGenerator.makeRng();
this.certificate = certificate;
this.privateKey = privateKey;
}
this(string configurationPath, DeveloperSession appleAccount) {
auto log = getLogger();
scope(success) log.debug_("Certificate retrieved successfully.");
string keyPath = configurationPath.buildPath("keys").buildPath(sha1Of(appleAccount.appleId).toHexString().toLower());
if (!file.exists(keyPath)) {
file.mkdirRecurse(keyPath);
}
keyFile = keyPath.buildPath("key.pem");
rng = RandomNumberGenerator.makeRng();
auto teams = appleAccount.listTeams().unwrap();
auto team = teams[0];
if (file.exists(keyFile)) {
log.debug_("A key has already been generated");
privateKey = RSAPrivateKey(loadKey(keyFile, rng));
log.debug_("Checking if any certificate online is matching the private key...");
auto certificates = appleAccount.listAllDevelopmentCerts!iOS(team).unwrap();
auto sideloaderCertificates = certificates.find!((cert) => cert.machineName == applicationName);
if (sideloaderCertificates.length != 0) {
Vector!ubyte certContent;
Vector!ubyte ourPublicKey = privateKey.x509SubjectPublicKey();
foreach (cert; sideloaderCertificates) {
certContent = Vector!ubyte(cert.certContent);
auto x509cert = X509Certificate(certContent, false);
if (x509cert.subjectPublicKey().x509SubjectPublicKey() == ourPublicKey) {
log.debug_("Matching certificate found.");
certificate = X509Certificate(Vector!ubyte(certContent), false);
return;
}
// +/
}
}
} else {
log.debug_("Generating a new RSA key");
privateKey = RSAPrivateKey(rng, 2048);
file.write(keyFile, botan.pubkey.pkcs8.PEM_encode(privateKey));
}
X509CertOptions subject;
subject.country = "US";
subject.state = "STATE";
subject.locality = "LOCAL";
subject.organization = "ORGANIZATION";
subject.common_name = "CN";
auto certRequest = createCertReq(subject, privateKey.m_priv, "SHA-256", rng);
log.debug_("Submitting a new certificate request to Apple...");
auto certificateId = appleAccount.submitDevelopmentCSR!iOS(team, certRequest.PEM_encode()).unwrap();
auto appleCertificateInfo = appleAccount.listAllDevelopmentCerts!iOS(team).unwrap().find!((cert) => cert.certificateId == certificateId)[0];
certificate = X509Certificate(Vector!ubyte(appleCertificateInfo.certContent), false);
}
}