Skip to content
This repository was archived by the owner on Mar 7, 2026. It is now read-only.

Commit 615669b

Browse files
authored
Fix bug
1 parent 8ad9304 commit 615669b

1 file changed

Lines changed: 158 additions & 51 deletions

File tree

Sources/prostore/install/GenerateCert.swift

Lines changed: 158 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,14 @@ public final class GenerateCert {
5151
rsaBits: Int32 = 2048,
5252
daysValid: Int32 = 36500) async throws -> [URL] {
5353
Logger.shared.log("Initializing OpenSSL...")
54-
_ = OpenSSL_add_all_algorithms()
55-
ERR_load_crypto_strings()
54+
55+
// Remove deprecated calls
56+
// _ = OpenSSL_add_all_algorithms() // Deprecated in OpenSSL 3.x
57+
// ERR_load_crypto_strings() // Deprecated in OpenSSL 3.x
58+
59+
// For OpenSSL 3.x, use explicit initialization
60+
OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS | OPENSSL_INIT_LOAD_CRYPTO_STRINGS, nil)
61+
OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG | OPENSSL_INIT_ADD_ALL_CIPHERS | OPENSSL_INIT_ADD_ALL_DIGESTS, nil)
5662

5763
Logger.shared.log("Generating CA key...")
5864
guard let caPkey = try generateRSAKey(bits: rsaBits) else { throw CertGenError.keyGenerationFailed("CA key generation failed") }
@@ -110,107 +116,208 @@ public final class GenerateCert {
110116
return url
111117
}
112118

113-
private static func generateRSAKey(bits: Int32) throws -> UnsafeMutablePointer<EVP_PKEY>? {
119+
private static func generateRSAKey(bits: Int32) throws -> OpaquePointer? {
114120
guard let rsa = RSA_new() else { throw CertGenError.keyGenerationFailed("RSA_new failed") }
115121
guard let bn = BN_new() else { RSA_free(rsa); throw CertGenError.keyGenerationFailed("BN_new failed") }
116-
if BN_set_word(bn, UInt(65537)) != 1 { BN_free(bn); RSA_free(rsa); throw CertGenError.keyGenerationFailed("BN_set_word failed") }
117-
if RSA_generate_key_ex(rsa, bits, bn, nil) != 1 { BN_free(bn); RSA_free(rsa); throw CertGenError.keyGenerationFailed("RSA_generate_key_ex failed") }
118-
BN_free(bn)
119-
guard let pkey = EVP_PKEY_new() else { RSA_free(rsa); throw CertGenError.keyGenerationFailed("EVP_PKEY_new failed") }
120-
if EVP_PKEY_assign_RSA(pkey, rsa) != 1 { EVP_PKEY_free(pkey); RSA_free(rsa); throw CertGenError.keyGenerationFailed("EVP_PKEY_assign_RSA failed") }
122+
123+
defer { BN_free(bn) }
124+
125+
if BN_set_word(bn, UInt(65537)) != 1 {
126+
RSA_free(rsa)
127+
throw CertGenError.keyGenerationFailed("BN_set_word failed")
128+
}
129+
130+
if RSA_generate_key_ex(rsa, bits, bn, nil) != 1 {
131+
RSA_free(rsa)
132+
throw CertGenError.keyGenerationFailed("RSA_generate_key_ex failed")
133+
}
134+
135+
guard let pkey = EVP_PKEY_new() else {
136+
RSA_free(rsa)
137+
throw CertGenError.keyGenerationFailed("EVP_PKEY_new failed")
138+
}
139+
140+
// Use EVP_PKEY_assign_RSA for OpenSSL 1.x compatibility
141+
// For OpenSSL 3.x, this should still work with the right headers
142+
if EVP_PKEY_assign(pkey, EVP_PKEY_RSA, rsa) != 1 {
143+
EVP_PKEY_free(pkey)
144+
RSA_free(rsa)
145+
throw CertGenError.keyGenerationFailed("EVP_PKEY_assign failed")
146+
}
147+
121148
return pkey
122149
}
123150

124-
private static func createSelfSignedCertificate(pkey: UnsafeMutablePointer<EVP_PKEY>?,
151+
private static func createSelfSignedCertificate(pkey: OpaquePointer?,
125152
commonName: String,
126153
days: Int32,
127-
isCA: Bool) throws -> UnsafeMutablePointer<X509>? {
154+
isCA: Bool) throws -> OpaquePointer? {
128155
guard let x509 = X509_new() else { throw CertGenError.x509CreationFailed("X509_new failed") }
156+
157+
defer {
158+
if let x509 = x509 {
159+
// Only free if error occurs
160+
}
161+
}
162+
129163
X509_set_version(x509, 2)
130-
if let serial = ASN1_INTEGER_new() { ASN1_INTEGER_set(serial, 1); X509_set_serialNumber(x509, serial); ASN1_INTEGER_free(serial) }
164+
165+
if let serial = ASN1_INTEGER_new() {
166+
ASN1_INTEGER_set(serial, 1)
167+
X509_set_serialNumber(x509, serial)
168+
ASN1_INTEGER_free(serial)
169+
}
170+
131171
X509_gmtime_adj(X509_get_notBefore(x509), 0)
132172
X509_gmtime_adj(X509_get_notAfter(x509), Int64(days) * 24 * 3600)
133173
X509_set_pubkey(x509, pkey)
134-
guard let name = X509_get_subject_name(x509) else { X509_free(x509); throw CertGenError.x509CreationFailed("X509_get_subject_name nil") }
174+
175+
guard let name = X509_get_subject_name(x509) else {
176+
X509_free(x509)
177+
throw CertGenError.x509CreationFailed("X509_get_subject_name nil")
178+
}
179+
135180
_ = addNameEntry(name: name, field: "C", value: "AU")
136181
_ = addNameEntry(name: name, field: "ST", value: "NSW")
137182
_ = addNameEntry(name: name, field: "L", value: "Sydney")
138183
_ = addNameEntry(name: name, field: "O", value: "MyCompany")
139184
_ = addNameEntry(name: name, field: "OU", value: "Dev")
140185
_ = addNameEntry(name: name, field: "CN", value: commonName)
186+
141187
X509_set_issuer_name(x509, name)
188+
142189
if isCA {
143-
if let ext = X509V3_EXT_conf_nid(nil, nil, NID_basic_constraints, "CA:TRUE") { X509_add_ext(x509, ext, -1); X509_EXTENSION_free(ext) }
144-
if let ext2 = X509V3_EXT_conf_nid(nil, nil, NID_key_usage, "keyCertSign,cRLSign") { X509_add_ext(x509, ext2, -1); X509_EXTENSION_free(ext2) }
190+
if let ext = X509V3_EXT_conf_nid(nil, nil, NID_basic_constraints, "CA:TRUE") {
191+
X509_add_ext(x509, ext, -1)
192+
X509_EXTENSION_free(ext)
193+
}
194+
if let ext2 = X509V3_EXT_conf_nid(nil, nil, NID_key_usage, "keyCertSign,cRLSign") {
195+
X509_add_ext(x509, ext2, -1)
196+
X509_EXTENSION_free(ext2)
197+
}
198+
}
199+
200+
if X509_sign(x509, pkey, EVP_sha256()) == 0 {
201+
X509_free(x509)
202+
throw CertGenError.x509CreationFailed("X509_sign failed")
145203
}
146-
if X509_sign(x509, pkey, EVP_sha256()) == 0 { X509_free(x509); throw CertGenError.x509CreationFailed("X509_sign failed") }
204+
147205
return x509
148206
}
149207

150-
private static func createCertificateSignedByCA(serverPKey: UnsafeMutablePointer<EVP_PKEY>?,
151-
caPkey: UnsafeMutablePointer<EVP_PKEY>?,
152-
caX509: UnsafeMutablePointer<X509>?,
208+
private static func createCertificateSignedByCA(serverPKey: OpaquePointer?,
209+
caPkey: OpaquePointer?,
210+
caX509: OpaquePointer?,
153211
commonName: String,
154-
days: Int32) throws -> UnsafeMutablePointer<X509>? {
212+
days: Int32) throws -> OpaquePointer? {
155213
guard let cert = X509_new() else { throw CertGenError.x509CreationFailed("X509_new failed") }
214+
215+
defer {
216+
if let cert = cert {
217+
// Only free if error occurs
218+
}
219+
}
220+
156221
X509_set_version(cert, 2)
157-
if let serial = ASN1_INTEGER_new() { ASN1_INTEGER_set(serial, Int(time(nil) & 0xffffffff)); X509_set_serialNumber(cert, serial); ASN1_INTEGER_free(serial) }
222+
223+
if let serial = ASN1_INTEGER_new() {
224+
ASN1_INTEGER_set(serial, Int(time(nil) & 0xffffffff))
225+
X509_set_serialNumber(cert, serial)
226+
ASN1_INTEGER_free(serial)
227+
}
228+
158229
X509_gmtime_adj(X509_get_notBefore(cert), 0)
159230
X509_gmtime_adj(X509_get_notAfter(cert), Int64(days) * 24 * 3600)
160231
X509_set_pubkey(cert, serverPKey)
161-
guard let subj = X509_get_subject_name(cert) else { X509_free(cert); throw CertGenError.x509CreationFailed("X509_get_subject_name nil") }
232+
233+
guard let subj = X509_get_subject_name(cert) else {
234+
X509_free(cert)
235+
throw CertGenError.x509CreationFailed("X509_get_subject_name nil")
236+
}
237+
162238
_ = addNameEntry(name: subj, field: "C", value: "AU")
163239
_ = addNameEntry(name: subj, field: "ST", value: "NSW")
164240
_ = addNameEntry(name: subj, field: "L", value: "Sydney")
165241
_ = addNameEntry(name: subj, field: "O", value: "MyCompany")
166242
_ = addNameEntry(name: subj, field: "OU", value: "Dev")
167243
_ = addNameEntry(name: subj, field: "CN", value: commonName)
168-
if let ca = caX509 { if let caSubject = X509_get_subject_name(ca) { X509_set_issuer_name(cert, caSubject) } }
169-
do { try addSubjectAltName_IP(cert: cert, ipString: "127.0.0.1") } catch { Logger.shared.log("Warning: SAN add failed: \(error)") }
170-
if let ext_bc = X509V3_EXT_conf_nid(nil, nil, NID_basic_constraints, "CA:FALSE") { X509_add_ext(cert, ext_bc, -1); X509_EXTENSION_free(ext_bc) }
171-
if let ext_ku = X509V3_EXT_conf_nid(nil, nil, NID_key_usage, "digitalSignature,keyEncipherment") { X509_add_ext(cert, ext_ku, -1); X509_EXTENSION_free(ext_ku) }
172-
guard let caKey = caPkey else { X509_free(cert); throw CertGenError.x509CreationFailed("CA private key missing") }
173-
if X509_sign(cert, caKey, EVP_sha256()) == 0 { X509_free(cert); throw CertGenError.x509CreationFailed("X509_sign with CA key failed") }
244+
245+
if let ca = caX509 {
246+
if let caSubject = X509_get_subject_name(ca) {
247+
X509_set_issuer_name(cert, caSubject)
248+
}
249+
}
250+
251+
// Use the simpler method for SAN
252+
do { try addSubjectAltName_IP_simple(cert: cert, ipString: "127.0.0.1") } catch {
253+
Logger.shared.log("Warning: SAN add failed: \(error)")
254+
}
255+
256+
if let ext_bc = X509V3_EXT_conf_nid(nil, nil, NID_basic_constraints, "CA:FALSE") {
257+
X509_add_ext(cert, ext_bc, -1)
258+
X509_EXTENSION_free(ext_bc)
259+
}
260+
261+
if let ext_ku = X509V3_EXT_conf_nid(nil, nil, NID_key_usage, "digitalSignature,keyEncipherment") {
262+
X509_add_ext(cert, ext_ku, -1)
263+
X509_EXTENSION_free(ext_ku)
264+
}
265+
266+
guard let caKey = caPkey else {
267+
X509_free(cert)
268+
throw CertGenError.x509CreationFailed("CA private key missing")
269+
}
270+
271+
if X509_sign(cert, caKey, EVP_sha256()) == 0 {
272+
X509_free(cert)
273+
throw CertGenError.x509CreationFailed("X509_sign with CA key failed")
274+
}
275+
174276
return cert
175277
}
176278

177-
@discardableResult private static func addNameEntry(name: UnsafeMutablePointer<X509_NAME>?, field: String, value: String) -> Int32 {
279+
@discardableResult private static func addNameEntry(name: OpaquePointer?, field: String, value: String) -> Int32 {
178280
guard let name = name else { return 0 }
179-
return X509_NAME_add_entry_by_txt(name, field, MBSTRING_ASC, value.withCString { UnsafeRawPointer($0) }, -1, -1, 0)
281+
return value.withCString { valuePtr in
282+
return X509_NAME_add_entry_by_txt(name, field, MBSTRING_ASC, valuePtr, -1, -1, 0)
283+
}
180284
}
181285

182-
private static func addSubjectAltName_IP(cert: UnsafeMutablePointer<X509>?, ipString: String) throws {
286+
// Simpler version that doesn't use deprecated stack functions
287+
private static func addSubjectAltName_IP_simple(cert: OpaquePointer?, ipString: String) throws {
183288
guard let cert = cert else { throw CertGenError.sanCreationFailed("cert nil") }
184-
var ipaddr = in_addr()
185-
guard inet_pton(AF_INET, ipString, &ipaddr) == 1 else { throw CertGenError.sanCreationFailed("inet_pton failed") }
186-
guard let gen = GENERAL_NAME_new() else { throw CertGenError.sanCreationFailed("GENERAL_NAME_new failed") }
187-
guard let ipOctet = ASN1_OCTET_STRING_new() else { GENERAL_NAME_free(gen); throw CertGenError.sanCreationFailed("ASN1_OCTET_STRING_new failed") }
188-
var rawIP = ipaddr.s_addr
189-
withUnsafePointer(to: &rawIP) { ptr in
190-
let p = UnsafeRawPointer(ptr)
191-
ASN1_OCTET_STRING_set(ipOctet, p.assumingMemoryBound(to: UInt8.self), 4)
192-
}
193-
GENERAL_NAME_set0_value(gen, GEN_IPADD, ipOctet)
194-
guard let stack = sk_GENERAL_NAME_new_null() else { GENERAL_NAME_free(gen); throw CertGenError.sanCreationFailed("sk_GENERAL_NAME_new_null failed") }
195-
sk_GENERAL_NAME_push(stack, gen)
196-
if X509_add1_ext_i2d(cert, NID_subject_alt_name, stack, 0, X509V3_ADD_REPLACE) != 1 {
197-
sk_GENERAL_NAME_pop_free(stack, { GENERAL_NAME_free(UnsafeMutablePointer(mutating: $0)) })
198-
throw CertGenError.sanCreationFailed("X509_add1_ext_i2d failed")
199-
}
200-
sk_GENERAL_NAME_pop_free(stack, { GENERAL_NAME_free(UnsafeMutablePointer(mutating: $0)) })
289+
290+
// Create SAN string in format "IP:127.0.0.1"
291+
let sanString = "IP:\(ipString)"
292+
293+
guard let ext = X509V3_EXT_conf_nid(nil, nil, NID_subject_alt_name, sanString) else {
294+
throw CertGenError.sanCreationFailed("X509V3_EXT_conf_nid failed for SAN")
295+
}
296+
297+
defer { X509_EXTENSION_free(ext) }
298+
299+
if X509_add_ext(cert, ext, -1) != 1 {
300+
throw CertGenError.sanCreationFailed("X509_add_ext failed for SAN")
301+
}
201302
}
202303

203-
private static func writePrivateKeyPEM(pkey: UnsafeMutablePointer<EVP_PKEY>?, to path: String) throws {
304+
private static func writePrivateKeyPEM(pkey: OpaquePointer?, to path: String) throws {
204305
guard let pkey = pkey else { throw CertGenError.writeFailed("pkey nil") }
205306
guard let bio = BIO_new_file(path, "w") else { throw CertGenError.writeFailed("BIO_new_file failed for \(path)") }
206307
defer { BIO_free_all(bio) }
207-
if PEM_write_bio_PrivateKey(bio, pkey, nil, nil, 0, nil, nil) != 1 { throw CertGenError.writeFailed("PEM_write_bio_PrivateKey failed for \(path)") }
308+
309+
if PEM_write_bio_PrivateKey(bio, pkey, nil, nil, 0, nil, nil) != 1 {
310+
throw CertGenError.writeFailed("PEM_write_bio_PrivateKey failed for \(path)")
311+
}
208312
}
209313

210-
private static func writeX509PEM(x509: UnsafeMutablePointer<X509>?, to path: String) throws {
314+
private static func writeX509PEM(x509: OpaquePointer?, to path: String) throws {
211315
guard let x509 = x509 else { throw CertGenError.writeFailed("x509 nil") }
212316
guard let bio = BIO_new_file(path, "w") else { throw CertGenError.writeFailed("BIO_new_file failed for \(path)") }
213317
defer { BIO_free_all(bio) }
214-
if PEM_write_bio_X509(bio, x509) != 1 { throw CertGenError.writeFailed("PEM_write_bio_X509 failed for \(path)") }
318+
319+
if PEM_write_bio_X509(bio, x509) != 1 {
320+
throw CertGenError.writeFailed("PEM_write_bio_X509 failed for \(path)")
321+
}
215322
}
216323
}

0 commit comments

Comments
 (0)