]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/ssl/cert_validate_message.cc
2 #include "acl/FilledChecklist.h"
3 #include "ssl/support.h"
4 #include "ssl/cert_validate_message.h"
5 #include "ssl/ErrorDetail.h"
9 Ssl::CertValidationMsg::composeRequest(CertValidationRequest
const &vcert
)
12 body
+= Ssl::CertValidationMsg::param_host
+ "=" + vcert
.domainName
;
14 body
+= "\n" + Ssl::CertValidationMsg::param_error
+ "=";
16 for (const Ssl::Errors
*err
= vcert
.errors
; err
; err
= err
->next
) {
19 body
+= GetErrorName(err
->element
);
24 if (vcert
.peerCerts
) {
26 Ssl::BIO_Pointer
bio(BIO_new(BIO_s_mem()));
27 for (int i
= 0; i
< sk_X509_num(vcert
.peerCerts
); ++i
) {
28 X509
*cert
= sk_X509_value(vcert
.peerCerts
, i
);
29 PEM_write_bio_X509(bio
.get(), cert
);
30 body
= body
+ "cert_" + xitoa(i
) + "=";
32 long len
= BIO_get_mem_data(bio
.get(), &ptr
);
33 body
.append(ptr
, len
);
34 // Normally openssl toolkit terminates Certificate with a '\n'.
35 if (ptr
[len
-1] != '\n')
37 if (!BIO_reset(bio
.get())) {
45 get_error_id(const char *label
, size_t len
)
47 const char *e
= label
+ len
-1;
48 while (e
!= label
&& xisdigit(*e
)) --e
;
50 return strtol(e
, 0 , 10);
54 Ssl::CertValidationMsg::parseResponse(CertValidationResponse
&resp
, STACK_OF(X509
) *peerCerts
, std::string
&error
)
56 std::vector
<CertItem
> certs
;
58 const char *param
= body
.c_str();
60 while(xisspace(*param
)) param
++;
64 size_t param_len
= strcspn(param
, "=\r\n");
65 if (param
[param_len
] != '=') {
66 debugs(83, 2, "Cert validator response parse error: " << param
);
69 const char *value
=param
+param_len
+1;
71 if (param_len
> param_cert
.length() &&
72 strncmp(param
, param_cert
.c_str(), param_cert
.length()) == 0) {
74 ci
.name
.assign(param
, param_len
);
76 readCertFromMemory(x509
, value
);
77 ci
.setCert(x509
.get());
80 const char *b
= strstr(value
, "-----END CERTIFICATE-----");
82 debugs(83, 2, "Cert Vailidator response parse error: Failed to find certificate boundary " << value
);
85 b
+= strlen("-----END CERTIFICATE-----");
90 size_t value_len
= strcspn(value
, "\r\n");
91 std::string
v(value
, value_len
);
93 debugs(83, 5, HERE
<< "Returned value: " << std::string(param
, param_len
).c_str() << ": " <<
96 int errorId
= get_error_id(param
, param_len
);
97 Ssl::CertValidationResponse::RecvdError
¤tItem
= resp
.getError(errorId
);
99 if (param_len
> param_error_name
.length() &&
100 strncmp(param
, param_error_name
.c_str(), param_error_name
.length()) == 0){
101 currentItem
.error_no
= Ssl::GetErrorCode(v
.c_str());
102 if (currentItem
.error_no
== SSL_ERROR_NONE
) {
103 debugs(83, 2, "Cert validator response parse error: Unknown SSL Error: " << v
);
106 } else if (param_len
> param_error_reason
.length() &&
107 strncmp(param
, param_error_reason
.c_str(), param_error_reason
.length()) == 0) {
108 currentItem
.error_reason
= v
;
109 } else if (param_len
> param_error_cert
.length() &&
110 strncmp(param
, param_error_cert
.c_str(), param_error_cert
.length()) == 0) {
112 if (X509
*cert
= getCertByName(certs
, v
)) {
113 debugs(83, 6, HERE
<< "The certificate with id \"" << v
<< "\" found.");
114 currentItem
.setCert(cert
);
116 //In this case we assume that the certID is one of the certificates sent
117 // to cert validator. The certificates sent to cert validator have names in
118 // form "cert_xx" where the "xx" is an integer represents the position of
119 // the certificate inside peer certificates list.
120 const int certId
= get_error_id(v
.c_str(), v
.length());
121 debugs(83, 6, HERE
<< "Cert index in peer certificates list:" << certId
);
122 //if certId is not correct sk_X509_value returns NULL
123 currentItem
.setCert(sk_X509_value(peerCerts
, certId
));
126 debugs(83, 2, "Cert validator response parse error: Unknown parameter name " << std::string(param
, param_len
).c_str());
131 param
= value
+ value_len
+1;
134 /*Run through parsed errors to check for errors*/
140 Ssl::CertValidationMsg::getCertByName(std::vector
<CertItem
> const &certs
, std::string
const & name
)
142 for (std::vector
<CertItem
>::const_iterator ci
= certs
.begin(); ci
!= certs
.end(); ++ci
) {
143 if (ci
->name
.compare(name
) == 0)
149 Ssl::CertValidationResponse::RecvdError
&
150 Ssl::CertValidationResponse::getError(int errorId
)
152 for(Ssl::CertValidationResponse::RecvdErrors::iterator i
= errors
.begin(); i
!= errors
.end(); ++i
){
153 if (i
->id
== errorId
)
156 Ssl::CertValidationResponse::RecvdError errItem
;
157 errItem
.id
= errorId
;
158 errors
.push_back(errItem
);
159 return errors
.back();
162 Ssl::CertValidationResponse::RecvdError::RecvdError(const RecvdError
&old
) {
163 error_no
= old
.error_no
;
164 error_reason
= old
.error_reason
;
169 Ssl::CertValidationResponse::RecvdError::~RecvdError() {
174 Ssl::CertValidationResponse::RecvdError
& Ssl::CertValidationResponse::RecvdError::operator = (const RecvdError
&old
) {
175 error_no
= old
.error_no
;
176 error_reason
= old
.error_reason
;
182 Ssl::CertValidationResponse::RecvdError::setCert(X509
*aCert
) {
187 CRYPTO_add(&cert
->references
, 1, CRYPTO_LOCK_X509
);
192 Ssl::CertValidationMsg::CertItem::CertItem(const CertItem
&old
)
199 Ssl::CertValidationMsg::CertItem
& Ssl::CertValidationMsg::CertItem::operator = (const CertItem
&old
)
206 Ssl::CertValidationMsg::CertItem::~CertItem()
213 Ssl::CertValidationMsg::CertItem::setCert(X509
*aCert
)
219 CRYPTO_add(&cert
->references
, 1, CRYPTO_LOCK_X509
);
224 const std::string
Ssl::CertValidationMsg::code_cert_validate("cert_validate");
225 const std::string
Ssl::CertValidationMsg::param_domain("domain");
226 const std::string
Ssl::CertValidationMsg::param_error("errors");
227 const std::string
Ssl::CertValidationMsg::param_cert("cert_");
228 const std::string
Ssl::CertValidationMsg::param_error_name("error_name_");
229 const std::string
Ssl::CertValidationMsg::param_error_reason("error_reason_");
230 const std::string
Ssl::CertValidationMsg::param_error_cert("error_cert_");