mirror of
https://github.com/status-im/nim-libp2p.git
synced 2025-02-27 20:10:50 +00:00
feat: encode certificates in PEM or DER
This commit is contained in:
parent
c26ef5fb52
commit
d615896924
@ -61,6 +61,10 @@ type
|
|||||||
certificate*: mbedtls_x509_crt
|
certificate*: mbedtls_x509_crt
|
||||||
extension*: P2pExtension
|
extension*: P2pExtension
|
||||||
|
|
||||||
|
type EncodingFormat* = enum
|
||||||
|
DER
|
||||||
|
PEM
|
||||||
|
|
||||||
proc ptrInc*(p: ptr byte, n: uint): ptr byte =
|
proc ptrInc*(p: ptr byte, n: uint): ptr byte =
|
||||||
## Utility function to increment a pointer by n bytes.
|
## Utility function to increment a pointer by n bytes.
|
||||||
cast[ptr byte](cast[uint](p) + n)
|
cast[ptr byte](cast[uint](p) + n)
|
||||||
@ -84,7 +88,7 @@ proc initializeDRBG() =
|
|||||||
mbedtls_entropy_func,
|
mbedtls_entropy_func,
|
||||||
addr entropy,
|
addr entropy,
|
||||||
cast[ptr byte](personalization.cstring),
|
cast[ptr byte](personalization.cstring),
|
||||||
personalization.len.uint
|
personalization.len.uint,
|
||||||
)
|
)
|
||||||
if ret != 0:
|
if ret != 0:
|
||||||
raise newException(KeyGenerationError, "Failed to seed CTR_DRBG")
|
raise newException(KeyGenerationError, "Failed to seed CTR_DRBG")
|
||||||
@ -247,7 +251,7 @@ proc makeLibp2pExtension(
|
|||||||
return generateSignedKey(signature, pubKeyBytes)
|
return generateSignedKey(signature, pubKeyBytes)
|
||||||
|
|
||||||
proc generate*(
|
proc generate*(
|
||||||
identityKeyPair: KeyPair
|
identityKeyPair: KeyPair, encodingFormat: EncodingFormat = EncodingFormat.DER
|
||||||
): (seq[byte], seq[byte]) {.
|
): (seq[byte], seq[byte]) {.
|
||||||
raises: [
|
raises: [
|
||||||
KeyGenerationError, CertificateCreationError, ASN1EncodingError,
|
KeyGenerationError, CertificateCreationError, ASN1EncodingError,
|
||||||
@ -261,8 +265,8 @@ proc generate*(
|
|||||||
##
|
##
|
||||||
## Returns:
|
## Returns:
|
||||||
## A tuple containing:
|
## A tuple containing:
|
||||||
## - The DER-encoded certificate.
|
## - The certificate.
|
||||||
## - The DER-encoded private key.
|
## - The private key.
|
||||||
##
|
##
|
||||||
## Raises:
|
## Raises:
|
||||||
## - `KeyGenerationError` if key generation fails.
|
## - `KeyGenerationError` if key generation fails.
|
||||||
@ -377,23 +381,22 @@ proc generate*(
|
|||||||
# Generate a random serial number
|
# Generate a random serial number
|
||||||
const SERIAL_LEN = 20
|
const SERIAL_LEN = 20
|
||||||
var serialBuffer: array[SERIAL_LEN, byte]
|
var serialBuffer: array[SERIAL_LEN, byte]
|
||||||
ret = mbedtls_ctr_drbg_random(addr ctrDrbg, addr serialBuffer[0], SERIAL_LEN);
|
ret = mbedtls_ctr_drbg_random(addr ctrDrbg, addr serialBuffer[0], SERIAL_LEN)
|
||||||
if ret != 0:
|
if ret != 0:
|
||||||
raise newException(CertificateCreationError, "Failed to generate serial number")
|
raise newException(CertificateCreationError, "Failed to generate serial number")
|
||||||
|
|
||||||
# Set the serial number
|
# Set the serial number
|
||||||
ret = mbedtls_x509write_crt_set_serial_raw(addr crt, addr serialBuffer[0], SERIAL_LEN);
|
ret = mbedtls_x509write_crt_set_serial_raw(addr crt, addr serialBuffer[0], SERIAL_LEN)
|
||||||
if ret != 0:
|
if ret != 0:
|
||||||
raise newException(CertificateCreationError, "Failed to set serial number")
|
raise newException(CertificateCreationError, "Failed to set serial number")
|
||||||
|
|
||||||
# Prepare Buffer for Certificate Serialization
|
# Prepare Buffer for Certificate Serialization
|
||||||
const CERT_BUFFER_SIZE = 4096
|
const CERT_BUFFER_SIZE = 4096
|
||||||
var
|
var certBuffer: array[CERT_BUFFER_SIZE, byte]
|
||||||
certBuffer: array[CERT_BUFFER_SIZE, byte]
|
var outputCertificate: seq[byte]
|
||||||
certLen: cint
|
|
||||||
|
|
||||||
# Write the Certificate in DER Format
|
if encodingFormat == EncodingFormat.DER:
|
||||||
certLen = mbedtls_x509write_crt_der(
|
let certLen: cint = mbedtls_x509write_crt_der(
|
||||||
addr crt,
|
addr crt,
|
||||||
addr certBuffer[0],
|
addr certBuffer[0],
|
||||||
CERT_BUFFER_SIZE.uint,
|
CERT_BUFFER_SIZE.uint,
|
||||||
@ -404,30 +407,52 @@ proc generate*(
|
|||||||
raise newException(
|
raise newException(
|
||||||
CertificateCreationError, "Failed to write certificate in DER format"
|
CertificateCreationError, "Failed to write certificate in DER format"
|
||||||
)
|
)
|
||||||
|
# Adjust the buffer to contain only the data
|
||||||
# Adjust the buffer to contain only the DER data
|
outputCertificate =
|
||||||
let certificateDer =
|
|
||||||
toSeq(certBuffer[(CERT_BUFFER_SIZE - certLen) ..< CERT_BUFFER_SIZE])
|
toSeq(certBuffer[(CERT_BUFFER_SIZE - certLen) ..< CERT_BUFFER_SIZE])
|
||||||
|
else:
|
||||||
|
let ret = mbedtls_x509write_crt_pem(
|
||||||
|
addr crt,
|
||||||
|
addr certBuffer[0],
|
||||||
|
CERT_BUFFER_SIZE.uint,
|
||||||
|
mbedtls_ctr_drbg_random,
|
||||||
|
addr ctrDrbg,
|
||||||
|
)
|
||||||
|
if ret != 0:
|
||||||
|
raise newException(
|
||||||
|
CertificateCreationError, "Failed to write certificate in PEM format"
|
||||||
|
)
|
||||||
|
let n = certBuffer.find(0'u8) # Find the index of the first null byte
|
||||||
|
outputCertificate = certBuffer[0 .. n - 1].toSeq()
|
||||||
|
|
||||||
# Serialize the Private Key in DER Format (PKCS#8)
|
# Serialize the Private Key
|
||||||
var
|
var privKeyBuffer: array[2048, byte]
|
||||||
privKeyBuffer: array[2048, byte]
|
var outputPrivateKey: seq[byte]
|
||||||
privKeyLen: cint
|
|
||||||
|
|
||||||
privKeyLen = mbedtls_pk_write_key_der(
|
if encodingFormat == EncodingFormat.DER:
|
||||||
|
let privKeyLen = mbedtls_pk_write_key_der(
|
||||||
addr certKey, addr privKeyBuffer[0], privKeyBuffer.len.uint
|
addr certKey, addr privKeyBuffer[0], privKeyBuffer.len.uint
|
||||||
)
|
)
|
||||||
if privKeyLen < 0:
|
if privKeyLen < 0:
|
||||||
raise newException(
|
raise newException(
|
||||||
CertificateCreationError, "Failed to write private key in DER format"
|
CertificateCreationError, "Failed to write private key in DER format"
|
||||||
)
|
)
|
||||||
|
# Adjust the buffer to contain only the data
|
||||||
# Adjust the buffer to contain only the DER data
|
outputPrivateKey =
|
||||||
let privateKeyDer =
|
|
||||||
toSeq(privKeyBuffer[(privKeyBuffer.len - privKeyLen) ..< privKeyBuffer.len])
|
toSeq(privKeyBuffer[(privKeyBuffer.len - privKeyLen) ..< privKeyBuffer.len])
|
||||||
|
else:
|
||||||
|
let ret = mbedtls_pk_write_key_pem(
|
||||||
|
addr certKey, addr privKeyBuffer[0], privKeyBuffer.len.uint
|
||||||
|
)
|
||||||
|
if ret != 0:
|
||||||
|
raise newException(
|
||||||
|
CertificateCreationError, "Failed to write private key in PEM format"
|
||||||
|
)
|
||||||
|
let n = privKeyBuffer.find(0'u8) # Find the index of the first null byte
|
||||||
|
outputPrivateKey = privKeyBuffer[0 .. n - 1].toSeq()
|
||||||
|
|
||||||
# Return the Serialized Certificate and Private Key
|
# Return the Serialized Certificate and Private Key
|
||||||
return (certificateDer, privateKeyDer)
|
return (outputCertificate, outputPrivateKey)
|
||||||
|
|
||||||
proc libp2pext(
|
proc libp2pext(
|
||||||
p_ctx: pointer,
|
p_ctx: pointer,
|
||||||
|
@ -12,7 +12,7 @@ suite "Certificate Tests":
|
|||||||
let keypair = KeyPair.random(Secp256k1, rng[]).tryGet()
|
let keypair = KeyPair.random(Secp256k1, rng[]).tryGet()
|
||||||
let peerId = PeerId.init(keypair.pubkey).tryGet()
|
let peerId = PeerId.init(keypair.pubkey).tryGet()
|
||||||
|
|
||||||
let certBytes = generate(keypair)[0]
|
let (certBytes, _) = generate(keypair, EncodingFormat.DER)
|
||||||
let cert = parse(certBytes)
|
let cert = parse(certBytes)
|
||||||
let ext = cert.extension
|
let ext = cert.extension
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user