XRootD
XrdTlsNotary.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d T l s N o t a r y . c c */
4 /* */
5 /* (c) 2019 by the Board of Trustees of the Leland Stanford, Jr., University */
6 /* Produced by Andrew Hanushevsky for Stanford University under contract */
7 /* DE-AC02-76-SFO0515 with the Department of Energy */
8 /* */
9 /* This file is part of the XRootD software suite. */
10 /* */
11 /* XRootD is free software: you can redistribute it and/or modify it under */
12 /* the terms of the GNU Lesser General Public License as published by the */
13 /* Free Software Foundation, either version 3 of the License, or (at your */
14 /* option) any later version. */
15 /* */
16 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
17 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
18 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
19 /* License for more details. */
20 /* */
21 /* You should have received a copy of the GNU Lesser General Public License */
22 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
23 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
24 /* */
25 /* The copyright holder's institutional names and contributor's names may not */
26 /* be used to endorse or promote products derived from this software without */
27 /* specific prior written permission of the institution or contributor. */
28 /******************************************************************************/
29 
30 #include "XrdNet/XrdNetAddrInfo.hh"
31 #include "XrdTls/XrdTlsNotary.hh"
32 
33 /******************************************************************************/
34 /* S t a t i c M e m b e r s */
35 /******************************************************************************/
36 
37 bool XrdTlsNotary::cnOK = true;
38 
39 /******************************************************************************/
40 /* L o c a l F u n c t i o n s */
41 /******************************************************************************/
42 
43 namespace
44 {
47 }
48 
51 
52 /******************************************************************************/
53 /* V a l i d a t e */
54 /******************************************************************************/
55 
56 const char *XrdTlsNotary::Validate(const SSL *ssl, const char *hName,
57  XrdNetAddrInfo *addrInfo)
58 {
60  bool dnsOK = (addrInfo != 0);
61  bool verChk= true;
62 
63 // Obtain the certificate
64 //
65  X509 *theCert = SSL_get_peer_certificate(ssl);
66  if (!theCert) return "certificate not present.";
67 
68 // Make sure the certificate was verified
69 //
70  if (verChk && (SSL_get_verify_result(ssl) != X509_V_OK))
71  {X509_free(theCert);
72  return "certificate has not been verified.";
73  }
74 
75 // The first step is to check if the hostname can be verified using the SAN
76 // extension. Various version of openSSL have ways of doing this but we
77 // rely on the manual method which works for all versions. Eventually, we
78 // will migrate to the "standard" way of doing this.
79 //
80  rc = matches_subject_alternative_name(hName, theCert);
81  X509_free(theCert);
82  if (rc == MatchFound) return 0;
83 
84 // If a SAN was present then we stop here unless we can use DNS.
85 //
86  if (rc != NoSANPresent && !dnsOK)
87  {if (rc == MatchNotFound) return "hostname not in SAN extension.";
88  return "malformed SAN extension.";
89  }
90 
91 // If we are allowed to use the common name, try that now.
92 //
93  if (cnOK || dnsOK)
94  {rc = matches_common_name(hName, theCert);
95  if (rc == MatchFound) return 0;
96  if (!dnsOK)
97  {if (rc == Error) return "malformed certificate.";
98  return "malformed common name.";
99  }
100  }
101 
102 // The last resort is to try using DNS if so allowed
103 //
104  if (dnsOK)
105  {const char *dnsErr = 0;
106  const char *dnsName = addrInfo->Name(0, &dnsErr);
107  if (dnsName)
108  {if (!strcmp(hName, dnsName)) return 0;
109  return "DNS registered name does not match.";
110  }
111  if (dnsErr) return dnsErr;
112  return "host not registered in DNS.";
113  }
114 
115 // Neither DNS nor common name is allowed here. That means there was no SAN.
116 //
117  return "required SAN extension missing.";
118 }
HostnameValidationResult
@ MatchNotFound
@ NoSANPresent
@ MatchFound
static HostnameValidationResult matches_common_name(const char *hostname, const X509 *server_cert)
static HostnameValidationResult matches_subject_alternative_name(const char *hostname, const X509 *server_cert)
const char * Name(const char *eName=0, const char **eText=0)
static const char * Validate(const SSL *ssl, const char *hName, XrdNetAddrInfo *netInfo=0)
Definition: XrdTlsNotary.cc:56