Я неправильно понял свои собственные цели.
В сообщении CertificateVerify
дайджест рукопожатия до этого момента. Сервер использует закрытый ключ своего сертификата для выполнения этой подписи. Как указано в спецификации TLS 1.3 , алгоритм подписи является частью структуры CertificateVerify
struct {
SignatureScheme algorithm;
opaque signature<0..2^16-1>;
} CertificateVerify;
Мне просто нужно извлечь ее и преобразовать в SecKeyAlgorithm
. Например (с C ++)
SecKeyAlgorithm keyAlgorithm;
// algorithm extracted from CertificateVerify
switch (algorithm) {
case SignatureScheme::ecdsa_secp256r1_sha256:
keyAlgorithm = kSecKeyAlgorithmECDSASignatureDigestX962SHA256;
break;
case SignatureScheme::rsa_pss_sha256:
keyAlgorithm = kSecKeyAlgorithmRSASignatureDigestPSSSHA256;
break;
case SignatureScheme::ed25519:
case SignatureScheme::ed448:
default:
throw std::runtime_error("unsupported peer cert type");
}
Затем я могу подтвердить, что сертификат поддерживает этот алгоритм
if (!SecKeyIsAlgorithmSupported(key, kSecKeyOperationTypeVerify, keyAlgorithm)) {
CFRelease(publicKey);
throw std::runtime_error("Unsupported signature scheme");
}
и, наконец, выполнить проверку с помощью signature
в CertificateVerify
и скомпилированные подписанные данные из рукопожатия
CFErrorRef error;
bool signatureVerified = SecKeyVerifySignature(key, keyAlgorithm, toBeSignedData, signature, &error);
if (!signatureVerified) {
CFRelease(error); // or use it
throw std::runtime_error("Signature verification failed");
}