OpenVPN 3 Core Library
Loading...
Searching...
No Matches
verify.hpp
Go to the documentation of this file.
1// OpenVPN -- An application to securely tunnel IP networks
2// over a single port, with support for SSL/TLS-based
3// session authentication and key exchange,
4// packet encryption, packet authentication, and
5// packet compression.
6//
7// Copyright (C) 2012- OpenVPN Inc.
8//
9// SPDX-License-Identifier: MPL-2.0 OR AGPL-3.0-only WITH openvpn3-openssl-exception
10//
11
12// Verify a signature using OpenSSL EVP interface
13
14#ifndef OPENVPN_OPENSSL_SIGN_VERIFY_H
15#define OPENVPN_OPENSSL_SIGN_VERIFY_H
16
17#include <string>
18#include <list>
19
20#include <openssl/ssl.h>
21#include <openssl/bio.h>
22
29
31
32namespace openvpn::OpenSSLSign {
33/*
34 * Verify signature.
35 * On success, return.
36 * On fail, throw exception.
37 */
38inline void verify(const OpenSSLPKI::X509 &cert,
39 const std::string &sig,
40 const std::string &data,
41 const std::string &digest)
42{
43 const EVP_MD *dig;
44 EVP_MD_CTX *md_ctx = nullptr;
45 EVP_PKEY *pkey = nullptr;
46
47 auto clean = Cleanup([&]()
48 {
49 if (pkey)
50 EVP_PKEY_free(pkey);
51 if (md_ctx)
52 {
53 EVP_MD_CTX_free(md_ctx);
54 } });
55
56 // get digest
57 dig = EVP_get_digestbyname(digest.c_str());
58 if (!dig)
59 throw Exception("OpenSSLSign::verify: unknown digest: " + digest);
60
61 // get public key
62 pkey = X509_get_pubkey(cert.obj());
63 if (!pkey)
64 throw Exception("OpenSSLSign::verify: no public key");
65
66 // convert signature from base64 to binary
67 BufferAllocated binsig(1024);
68 try
69 {
70 base64->decode(binsig, sig);
71 }
72 catch (const std::exception &e)
73 {
74 throw Exception(std::string("OpenSSLSign::verify: base64 decode error on signature: ") + e.what());
75 }
76
77 // initialize digest context
78 md_ctx = EVP_MD_CTX_new();
79
80 // verify signature
81 EVP_VerifyInit(md_ctx, dig);
82 EVP_VerifyUpdate(md_ctx, data.c_str(), data.length());
83 if (EVP_VerifyFinal(md_ctx, binsig.c_data(), numeric_cast<unsigned int>(binsig.length()), pkey) != 1)
84 throw OpenSSLException("OpenSSLSign::verify: verification failed");
85}
86} // namespace openvpn::OpenSSLSign
87
88#endif
size_t decode(void *data, size_t len, const std::string &str) const
Definition base64.hpp:186
const T * c_data() const
Returns a const pointer to the start of the buffer.
Definition buffer.hpp:1194
size_t length() const
Returns the length of the buffer.
Definition buffer.hpp:1188
::X509 * obj() const
Definition x509.hpp:82
void verify(const OpenSSLPKI::X509 &cert, const std::string &sig, const std::string &data, const std::string &digest)
Definition verify.hpp:38
CleanupType< F > Cleanup(F method) noexcept
Definition cleanup.hpp:43
const Base64 * base64
Definition base64.hpp:299