-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* msquic refactor * comment * refactor to use handler * avoid use CoreFoundation api * fix submodule * fix * fix
- Loading branch information
Showing
196 changed files
with
44,816 additions
and
1,784 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
#include <openssl/x509.h> | ||
#include <openssl/x509v3.h> | ||
#include <openssl/err.h> | ||
#include <openssl/pkcs12.h> | ||
#include <openssl/ssl3.h> | ||
|
||
#include "helpers.h" | ||
|
||
int generate_self_signed_cert_and_pkcs12( | ||
const unsigned char *private_key_buf, | ||
size_t private_key_len, | ||
const char *alt_name, // null terminated string | ||
unsigned char **pkcs12_data, | ||
int *pkcs12_len | ||
) { | ||
X509 *cert = NULL; | ||
PKCS12 *p12 = NULL; | ||
EVP_PKEY *ed25519_key = NULL; | ||
unsigned char *temp_buf = NULL; | ||
int ret = 1; | ||
|
||
// Create EVP_PKEY from the provided Ed25519 private key buffer | ||
ed25519_key = EVP_PKEY_new_raw_private_key(EVP_PKEY_ED25519, NULL, private_key_buf, private_key_len); | ||
if (!ed25519_key) { | ||
goto cleanup; | ||
} | ||
|
||
// Create a new X509 certificate | ||
cert = X509_new(); | ||
if (!cert) { | ||
goto cleanup; | ||
} | ||
|
||
// Set version to X509v3 | ||
X509_set_version(cert, 2); | ||
|
||
// Set serial number (you might want to generate this randomly) | ||
ASN1_INTEGER_set(X509_get_serialNumber(cert), 1); | ||
|
||
// // Set validity period (1 year) | ||
// X509_gmtime_adj(X509_get_notBefore(cert), 0); | ||
// X509_gmtime_adj(X509_get_notAfter(cert), 31536000L); | ||
|
||
// Set subject and issuer (self-signed, so they're the same) | ||
X509_NAME *name = X509_get_subject_name(cert); | ||
X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (unsigned char *)"Self-Signed Cert", -1, -1, 0); | ||
X509_set_issuer_name(cert, name); | ||
|
||
// Set public key | ||
X509_set_pubkey(cert, ed25519_key); | ||
|
||
// Add Subject Alternative Name extension | ||
GENERAL_NAMES *alt_names = GENERAL_NAMES_new(); | ||
GENERAL_NAME *gen_name = GENERAL_NAME_new(); | ||
ASN1_IA5STRING *ia5 = ASN1_IA5STRING_new(); | ||
ASN1_STRING_set(ia5, alt_name, -1); | ||
GENERAL_NAME_set0_value(gen_name, GEN_DNS, ia5); | ||
sk_GENERAL_NAME_push(alt_names, gen_name); | ||
X509_add1_ext_i2d(cert, NID_subject_alt_name, alt_names, 0, 0); | ||
GENERAL_NAMES_free(alt_names); | ||
|
||
// Self-sign the certificate | ||
if (!X509_sign(cert, ed25519_key, NULL)) { | ||
goto cleanup; | ||
} | ||
|
||
// Create PKCS12 structure | ||
p12 = PKCS12_create(NULL, "My Certificate", ed25519_key, cert, NULL, 0, 0, 0, 0, 0); | ||
if (!p12) { | ||
goto cleanup; | ||
} | ||
|
||
// Get the size of the DER-encoded PKCS12 structure | ||
*pkcs12_len = i2d_PKCS12(p12, NULL); | ||
if (*pkcs12_len <= 0) { | ||
goto cleanup; | ||
} | ||
|
||
// Allocate memory for the DER-encoded PKCS12 structure | ||
*pkcs12_data = malloc(*pkcs12_len); | ||
if (!*pkcs12_data) { | ||
goto cleanup; | ||
} | ||
|
||
// Reset the pointer to the start of the buffer | ||
temp_buf = *pkcs12_data; | ||
|
||
// Actually encode the PKCS12 structure | ||
*pkcs12_len = i2d_PKCS12(p12, &temp_buf); | ||
if (*pkcs12_len <= 0) { | ||
ret = 6; | ||
free(*pkcs12_data); | ||
*pkcs12_data = NULL; | ||
*pkcs12_len = 0; | ||
goto cleanup; | ||
} | ||
|
||
ret = 0; | ||
|
||
cleanup: | ||
if (ret != 0) { | ||
ret = ERR_get_error(); | ||
|
||
} | ||
X509_free(cert); | ||
PKCS12_free(p12); | ||
EVP_PKEY_free(ed25519_key); | ||
return ret; | ||
} | ||
|
||
char *get_error_string(int error) { | ||
return ERR_error_string(error, NULL); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
#include <stddef.h> | ||
#include <arpa/inet.h> | ||
|
||
int generate_self_signed_cert_and_pkcs12( | ||
const unsigned char *private_key_buf, | ||
size_t private_key_len, | ||
const char *alt_name, // null terminated string | ||
unsigned char **pkcs12_data, | ||
int *pkcs12_len | ||
); | ||
|
||
char *get_error_string(int error); | ||
|
||
static inline uint16_t helper_ntohs(in_port_t netport) { | ||
return ntohs(netport); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import CHelpers | ||
import Foundation | ||
import msquic | ||
#if canImport(Glibc) | ||
import Glibc | ||
#elseif canImport(Darwin) | ||
import Darwin | ||
#endif | ||
|
||
public struct NetAddr: Hashable, Sendable { | ||
var ipAddress: String | ||
var port: UInt16 | ||
var ipv4: Bool | ||
|
||
public init(ipAddress: String, port: UInt16, ipv4: Bool = false) { | ||
self.ipAddress = ipAddress | ||
self.port = port | ||
self.ipv4 = ipv4 | ||
} | ||
|
||
public init(quicAddr: QUIC_ADDR) { | ||
let (host, port, ipv4) = parseQuicAddr(quicAddr) ?? ("::dead:beef", 0, false) | ||
ipAddress = host | ||
self.port = port | ||
self.ipv4 = ipv4 | ||
} | ||
|
||
func toQuicAddr() -> QUIC_ADDR? { | ||
var addr = QUIC_ADDR() | ||
let cstring = ipAddress.cString(using: .utf8) | ||
guard cstring != nil else { | ||
return nil | ||
} | ||
let success = QuicAddrFromString(cstring!, port, &addr) | ||
guard success == 1 else { | ||
return nil | ||
} | ||
return addr | ||
} | ||
} | ||
|
||
extension NetAddr: CustomStringConvertible { | ||
public var description: String { | ||
if ipv4 { | ||
"\(ipAddress):\(port)" | ||
} else { | ||
"[\(ipAddress)]:\(port)" | ||
} | ||
} | ||
} | ||
|
||
func parseQuicAddr(_ addr: QUIC_ADDR) -> (String, UInt16, Bool)? { | ||
let ipv6 = addr.Ip.sa_family == QUIC_ADDRESS_FAMILY(QUIC_ADDRESS_FAMILY_INET6) | ||
let port = if ipv6 { | ||
helper_ntohs(addr.Ipv6.sin6_port) | ||
} else { | ||
helper_ntohs(addr.Ipv4.sin_port) | ||
} | ||
var addr = addr | ||
if ipv6 { | ||
addr.Ipv6.sin6_port = 0 | ||
} else { | ||
addr.Ipv4.sin_port = 0 | ||
} | ||
var buffer = QUIC_ADDR_STR() | ||
let success = QuicAddrToString(&addr, &buffer) | ||
guard success == 1 else { | ||
return nil | ||
} | ||
let ipaddress = withUnsafePointer(to: buffer.Address) { ptr in | ||
ptr.withMemoryRebound(to: CChar.self, capacity: Int(64)) { ptr in | ||
String(cString: ptr, encoding: .utf8)! | ||
} | ||
} | ||
|
||
return (ipaddress, port, ipv6) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import msquic | ||
import Utils | ||
|
||
public final class QuicAPI: Sendable { | ||
private let api: SendablePointer<QUIC_API_TABLE> | ||
|
||
public init() throws(QuicError) { | ||
var ptr: UnsafeRawPointer? | ||
try MsQuicOpenVersion(2, &ptr).requireSucceeded("MsQuicOpenVersion") | ||
|
||
api = ptr!.assumingMemoryBound( | ||
to: QUIC_API_TABLE.self | ||
).asSendable | ||
} | ||
|
||
deinit { | ||
MsQuicClose(api.value) | ||
} | ||
|
||
func call( | ||
_ message: String, | ||
fn: (UnsafePointer<QUIC_API_TABLE>) throws(QuicError) -> UInt32 | ||
) throws(QuicError) { | ||
try fn(api.value).requireSucceeded(message) | ||
} | ||
|
||
func call( | ||
fn: (UnsafePointer<QUIC_API_TABLE>) -> Void | ||
) { | ||
fn(api.value) | ||
} | ||
|
||
public static let shared = try! QuicAPI() | ||
} | ||
|
||
extension UInt32 { | ||
private var asQuicStatus: QuicStatus { | ||
QuicStatus(rawValue: self) | ||
} | ||
|
||
fileprivate func requireSucceeded(_ message: String) throws(QuicError) { | ||
try asQuicStatus.requireSucceeded(message) | ||
} | ||
} |
Oops, something went wrong.