OpenVPN 3 Core Library
Loading...
Searching...
No Matches
httpdigest.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// Low-level methods used to implement HTTP Digest authentication
13
14#ifndef OPENVPN_PROXY_HTTPDIGEST_H
15#define OPENVPN_PROXY_HTTPDIGEST_H
16
17#include <cstring> // for std::strlen and others
18#include <string>
19
21
23
24class Digest
25{
26 public:
27 // calculate H(A1) as per spec
28 static std::string calcHA1(DigestFactory &digest_factory,
29 const std::string &alg,
30 const std::string &username,
31 const std::string &realm,
32 const std::string &password,
33 const std::string &nonce,
34 const std::string &cnonce)
35 {
36 HashString h1(digest_factory, CryptoAlgs::MD5);
37 h1.update(username);
38 h1.update(':');
39 h1.update(realm);
40 h1.update(':');
41 h1.update(password);
42 BufferPtr result = h1.final();
43
44 if (string::strcasecmp(alg, "md5-sess") == 0)
45 {
46 HashString h2(digest_factory, CryptoAlgs::MD5);
47 h2.update(*result);
48 h2.update(':');
49 h2.update(nonce);
50 h2.update(':');
51 h2.update(cnonce);
52 result = h2.final();
53 }
54 return render_hex_generic(*result);
55 }
56
57 // calculate request-digest/response-digest as per HTTP Digest spec
58 static std::string calcResponse(DigestFactory &digest_factory,
59 const std::string &hA1, // H(A1)
60 const std::string &nonce, // nonce from server
61 const std::string &nonce_count, // 8 hex digits
62 const std::string &cnonce, // client nonce
63 const std::string &qop, // qop-value: "", "auth", "auth-int"
64 const std::string &method, // method from the request
65 const std::string &digestUri, // requested URI
66 const std::string &hEntity) // H(entity body) if qop="auth-int"
67 {
68 // calculate H(A2)
69 HashString h1(digest_factory, CryptoAlgs::MD5);
70 h1.update(method);
71 h1.update(':');
72 h1.update(digestUri);
73 if (string::strcasecmp(qop, "auth-int") == 0)
74 {
75 h1.update(':');
76 h1.update(hEntity);
77 }
78 const std::string hA2 = h1.final_hex();
79
80 // calculate response
81 HashString h2(digest_factory, CryptoAlgs::MD5);
82 h2.update(hA1);
83 h2.update(':');
84 h2.update(nonce);
85 h2.update(':');
86 if (!qop.empty())
87 {
88 h2.update(nonce_count);
89 h2.update(':');
90 h2.update(cnonce);
91 h2.update(':');
92 h2.update(qop);
93 h2.update(':');
94 }
95 h2.update(hA2);
96 return h2.final_hex();
97 }
98};
99} // namespace openvpn::HTTPProxy
100
101#endif
static std::string calcResponse(DigestFactory &digest_factory, const std::string &hA1, const std::string &nonce, const std::string &nonce_count, const std::string &cnonce, const std::string &qop, const std::string &method, const std::string &digestUri, const std::string &hEntity)
static std::string calcHA1(DigestFactory &digest_factory, const std::string &alg, const std::string &username, const std::string &realm, const std::string &password, const std::string &nonce, const std::string &cnonce)
std::string final_hex()
Definition hashstr.hpp:68
void update(const std::string &str)
Definition hashstr.hpp:32
BufferPtr final()
Definition hashstr.hpp:52
int strcasecmp(const char *s1, const char *s2)
Definition string.hpp:29
std::string render_hex_generic(const V &data, const bool caps=false)
Definition hexstr.hpp:230