feature. See also
. The project being documented here (as the example) is the Zig library itself.
Client.CertificatePublicKey
const CertificatePublicKey = struct
File
Code
const CertificatePublicKey = struct {
algo: Certificate.AlgorithmCategory,
buf: [600]u8,
len: u16,
fn init(
cert_pub_key: *CertificatePublicKey,
algo: Certificate.AlgorithmCategory,
pub_key: []const u8,
) error{CertificatePublicKeyInvalid}!void {
if (pub_key.len > cert_pub_key.buf.len) return error.CertificatePublicKeyInvalid;
cert_pub_key.algo = algo;
@memcpy(cert_pub_key.buf[0..pub_key.len], pub_key);
cert_pub_key.len = @intCast(pub_key.len);
}
const VerifyError = error{ TlsDecodeError, TlsBadSignatureScheme, InvalidEncoding } ||
crypto.errors.EncodingError ||
crypto.errors.NotSquareError ||
crypto.errors.NonCanonicalError ||
SchemeEcdsa(.ecdsa_secp256r1_sha256).Signature.VerifyError ||
SchemeEcdsa(.ecdsa_secp384r1_sha384).Signature.VerifyError ||
error{TlsBadRsaSignatureBitCount} ||
Certificate.rsa.PublicKey.ParseDerError ||
Certificate.rsa.PublicKey.FromBytesError ||
Certificate.rsa.PSSSignature.VerifyError ||
Certificate.rsa.PKCS1v1_5Signature.VerifyError ||
SchemeEddsa(.ed25519).Signature.VerifyError;
fn verifySignature(
cert_pub_key: *const CertificatePublicKey,
sigd: *tls.Decoder,
msg: []const []const u8,
) VerifyError!void {
const pub_key = cert_pub_key.buf[0..cert_pub_key.len];
try sigd.ensure(2 + 2);
const scheme = sigd.decode(tls.SignatureScheme);
const sig_len = sigd.decode(u16);
try sigd.ensure(sig_len);
const encoded_sig = sigd.slice(sig_len);
if (cert_pub_key.algo != @as(Certificate.AlgorithmCategory, switch (scheme) {
.ecdsa_secp256r1_sha256,
.ecdsa_secp384r1_sha384,
=> .X9_62_id_ecPublicKey,
.rsa_pkcs1_sha256,
.rsa_pkcs1_sha384,
.rsa_pkcs1_sha512,
.rsa_pss_rsae_sha256,
.rsa_pss_rsae_sha384,
.rsa_pss_rsae_sha512,
.rsa_pkcs1_sha1,
=> .rsaEncryption,
.rsa_pss_pss_sha256,
.rsa_pss_pss_sha384,
.rsa_pss_pss_sha512,
=> .rsassa_pss,
else => return error.TlsBadSignatureScheme,
})) return error.TlsBadSignatureScheme;
switch (scheme) {
inline .ecdsa_secp256r1_sha256,
.ecdsa_secp384r1_sha384,
=> |comptime_scheme| {
const Ecdsa = SchemeEcdsa(comptime_scheme);
const sig = try Ecdsa.Signature.fromDer(encoded_sig);
const key = try Ecdsa.PublicKey.fromSec1(pub_key);
var ver = try sig.verifier(key);
for (msg) |part| ver.update(part);
try ver.verify();
},
inline .rsa_pkcs1_sha256,
.rsa_pkcs1_sha384,
.rsa_pkcs1_sha512,
.rsa_pss_rsae_sha256,
.rsa_pss_rsae_sha384,
.rsa_pss_rsae_sha512,
.rsa_pss_pss_sha256,
.rsa_pss_pss_sha384,
.rsa_pss_pss_sha512,
.rsa_pkcs1_sha1,
=> |comptime_scheme| {
const RsaSignature = SchemeRsa(comptime_scheme);
const Hash = SchemeHash(comptime_scheme);
const PublicKey = Certificate.rsa.PublicKey;
const components = try PublicKey.parseDer(pub_key);
const exponent = components.exponent;
const modulus = components.modulus;
switch (modulus.len) {
inline 128, 256, 384, 512 => |modulus_len| {
const key: PublicKey = try .fromBytes(exponent, modulus);
const sig = RsaSignature.fromBytes(modulus_len, encoded_sig);
try RsaSignature.concatVerify(modulus_len, sig, msg, key, Hash);
},
else => return error.TlsBadRsaSignatureBitCount,
}
},
inline .ed25519 => |comptime_scheme| {
const Eddsa = SchemeEddsa(comptime_scheme);
if (encoded_sig.len != Eddsa.Signature.encoded_length) return error.InvalidEncoding;
const sig = Eddsa.Signature.fromBytes(encoded_sig[0..Eddsa.Signature.encoded_length].*);
if (pub_key.len != Eddsa.PublicKey.encoded_length) return error.InvalidEncoding;
const key = try Eddsa.PublicKey.fromBytes(pub_key[0..Eddsa.PublicKey.encoded_length].*);
var ver = try sig.verifier(key);
for (msg) |part| ver.update(part);
try ver.verify();
},
else => unreachable,
}
}
}