XRootD
XrdCryptoX509.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d C r y p t o X 5 0 9 . c c */
4 /* */
5 /* (c) 2005 G. Ganis , CERN */
6 /* */
7 /* This file is part of the XRootD software suite. */
8 /* */
9 /* XRootD is free software: you can redistribute it and/or modify it under */
10 /* the terms of the GNU Lesser General Public License as published by the */
11 /* Free Software Foundation, either version 3 of the License, or (at your */
12 /* option) any later version. */
13 /* */
14 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
15 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
16 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
17 /* License for more details. */
18 /* */
19 /* You should have received a copy of the GNU Lesser General Public License */
20 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
21 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
22 /* */
23 /* The copyright holder's institutional names and contributor's names may not */
24 /* be used to endorse or promote products derived from this software without */
25 /* specific prior written permission of the institution or contributor. */
26 /* (c) 2012 by the Board of Trustees of the Leland Stanford, Jr., University */
27 /* All Rights Reserved */
28 /* Produced by Andrew Hanushevsky for Stanford University under contract */
29 /* DE-AC02-76-SFO0515 with the Department of Energy */
30 /******************************************************************************/
31 
32 /* ************************************************************************** */
33 /* */
34 /* Abstract interface for X509 certificates. */
35 /* Allows to plug-in modules based on different crypto implementation */
36 /* (OpenSSL, Botan, ...) */
37 /* */
38 /* ************************************************************************** */
39 #include <ctime>
40 
43 
44 const char *XrdCryptoX509::ctype[4] = { "Unknown", "CA", "EEC", "Proxy" };
45 
46 #define kAllowedSkew 600
47 
48 //_____________________________________________________________________________
50 {
51  // Dump content
52  EPNAME("X509::Dump");
53 
54  // Time strings
55  struct tm tst;
56  char stbeg[256] = {0};
57  time_t tbeg = NotBefore();
58  localtime_r(&tbeg,&tst);
59  asctime_r(&tst,stbeg);
60  stbeg[strlen(stbeg)-1] = 0;
61  char stend[256] = {0};
62  time_t tend = NotAfter();
63  localtime_r(&tend,&tst);
64  asctime_r(&tst,stend);
65  stend[strlen(stend)-1] = 0;
66 
67  PRINT("+++++++++++++++ X509 dump +++++++++++++++++++++++");
68  PRINT("+");
69  PRINT("+ File: "<<ParentFile());
70  PRINT("+");
71  PRINT("+ Type: "<<Type());
72  PRINT("+ Serial Number: "<<SerialNumber());
73  PRINT("+ Subject: "<<Subject());
74  PRINT("+ Subject hash: "<<SubjectHash(0));
75  PRINT("+ Issuer: "<<Issuer());
76  PRINT("+ Issuer hash: "<<IssuerHash(0));
77  PRINT("+");
78  if (IsExpired()) {
79  PRINT("+ Validity: (expired!)");
80  } else {
81  PRINT("+ Validity:");
82  }
83  PRINT("+ NotBefore: "<<tbeg<<" UTC - "<<stbeg);
84  PRINT("+ NotAfter: "<<tend<<" UTC - "<<stend);
85  PRINT("+");
86  if (PKI()) {
87  PRINT("+ PKI: "<<PKI()->Status());
88  } else {
89  PRINT("+ PKI: missing");
90  }
91  PRINT("+");
92  PRINT("+++++++++++++++++++++++++++++++++++++++++++++++++");
93 }
94 
95 
96 //_____________________________________________________________________________
98 {
99  // Return number of bits in key
100  ABSTRACTMETHOD("XrdCryptoX509::BitStrength");
101  return -1;
102 }
103 
104 //_____________________________________________________________________________
106 {
107  // Check validity at UTC time 'when'. Use when =0 (default) to check
108  // at present time.
109 
110  int now = (when > 0) ? when : (int)time(0);
111  return (now >= (NotBefore()-kAllowedSkew) && now <= NotAfter());
112 }
113 
114 //_____________________________________________________________________________
116 {
117  // Check expiration at UTC time 'when'. Use when =0 (default) to check
118  // at present time.
119 
120  int now = (when > 0) ? when : (int)time(0);
121  return (now > NotAfter());
122 }
123 
124 //_____________________________________________________________________________
126 {
127  // Begin-validity time in secs since Epoch
128  ABSTRACTMETHOD("XrdCryptoX509::NotBefore");
129  return -1;
130 }
131 
132 //_____________________________________________________________________________
134 {
135  // End-validity time in secs since Epoch
136  ABSTRACTMETHOD("XrdCryptoX509::NotAfter");
137  return -1;
138 }
139 
140 //_____________________________________________________________________________
142 {
143  // Return subject name
144  ABSTRACTMETHOD("XrdCryptoX509::Subject");
145  return (const char *)0;
146 }
147 
148 //_____________________________________________________________________________
150 {
151  // Return parent file name
152  ABSTRACTMETHOD("XrdCryptoX509::ParentFile");
153  return (const char *)0;
154 }
155 
156 //_____________________________________________________________________________
158 {
159  // Return issuer name
160  ABSTRACTMETHOD("XrdCryptoX509::Issuer");
161  return (const char *)0;
162 }
163 
164 //_____________________________________________________________________________
166 {
167  // Return subject name
168  ABSTRACTMETHOD("XrdCryptoX509::SubjectHash");
169  return (const char *)0;
170 }
171 
172 //_____________________________________________________________________________
174 {
175  // Return issuer name
176  ABSTRACTMETHOD("XrdCryptoX509::IssuerHash");
177  return (const char *)0;
178 }
179 
180 //_____________________________________________________________________________
182 {
183  // Return underlying certificate in raw format
184  ABSTRACTMETHOD("XrdCryptoX509::Opaque");
185  return (XrdCryptoX509data)0;
186 }
187 
188 //_____________________________________________________________________________
190 {
191  // Return PKI key of the certificate
192  ABSTRACTMETHOD("XrdCryptoX509::PKI");
193  return (XrdCryptoRSA *)0;
194 }
195 
196 //_____________________________________________________________________________
198 {
199  // Set PKI
200 
201  ABSTRACTMETHOD("XrdCryptoX509::SetPKI");
202 }
203 
204 //_____________________________________________________________________________
206 {
207  // Return issuer name
208  ABSTRACTMETHOD("XrdCryptoX509::SerialNumber");
209  return -1;
210 }
211 
212 //_____________________________________________________________________________
214 {
215  // Return issuer name
216  ABSTRACTMETHOD("XrdCryptoX509::SerialNumberString");
217  return XrdOucString("");
218 }
219 
220 //_____________________________________________________________________________
222 {
223  // Return issuer name
224  ABSTRACTMETHOD("XrdCryptoX509::GetExtension");
225  return (XrdCryptoX509data)0;
226 }
227 
228 //_____________________________________________________________________________
230 {
231  // EXport in form of bucket
232  ABSTRACTMETHOD("XrdCryptoX509::Export");
233  return (XrdSutBucket *)0;
234 }
235 
236 //_____________________________________________________________________________
238 {
239  // Verify certificate signature with pub key of ref cert
240  ABSTRACTMETHOD("XrdCryptoX509::Verify");
241  return 0;
242 }
243 
244 //_____________________________________________________________________________
246 {
247  // Dump extensions, if any
248  ABSTRACTMETHOD("XrdCryptoX509::DumpExtensions");
249  return -1;
250 }
251 
252 //_____________________________________________________________________________
253 bool XrdCryptoX509::MatchHostnames(const char * match_pattern, const char * hostname)
254 {
255  // Compare two hostnames and see if they are the same, including wildcards.
256  //
257  // For example,
258  //
259  // - foo.example.com and foo.example.com are considered equal.
260  // - bar.example.com and foo.example.com are not equal.
261  // - *.example.com and foo.example.com are equal.
262  // - *.example.com and foo.bar.example.com are NOT equal (wildcard applies to a single label).
263  // - FOO.example.com and foo.EXAMPLE.COM are equal (comparison is not case sensitive).
264  // - F*.com and foo.com are equal
265  //
266  // Returns true if the hostnames are considered a match
267 
268  XrdOucString mpatt(match_pattern), hname(hostname);
269 
270  // Not empty
271  if (!mpatt.length() || !hname.length()) return false;
272 
273  // Create a lowercase copy of both hostnames
274  mpatt.lower(0);
275  hname.lower(0);
276 
277  // Are they equal?
278  if (mpatt == hname) return true;
279 
280  bool theydomatch = false;
281 
282  // Get first token of both strings
283 // int mfrom = -1, hfrom = -1;
284  int mfrom = 0, hfrom = 0;
285  XrdOucString mfirst, hfirst;
286  if (((mfrom = mpatt.tokenize(mfirst, mfrom, '.')) != -1) &&
287  ((hfrom = hname.tokenize(hfirst, hfrom, '.')) != -1)) {
288  if (hfirst.matches(mfirst.c_str())) {
289  // First tokens matches, the rest should match without wildcards
290  mpatt.erasefromstart(mfrom);
291  hname.erasefromstart(hfrom);
292  if ((hname == mpatt) ||
293  (!hname.length() && !mpatt.length())) theydomatch = true;
294  }
295  }
296 
297  return theydomatch;
298 }
long long kXR_int64
Definition: XPtypes.hh:98
#define EPNAME(x)
Definition: XrdBwmTrace.hh:56
#define ABSTRACTMETHOD(x)
Definition: XrdCryptoAux.hh:41
#define kAllowedSkew
void * XrdCryptoX509data
#define PRINT(y)
virtual bool Verify(XrdCryptoX509 *ref)
virtual XrdCryptoX509data GetExtension(const char *oid)
virtual int BitStrength()
const char * IssuerHash()
virtual const char * Subject()
const char * Type(EX509Type t=kUnknown) const
virtual void SetPKI(XrdCryptoX509data pki)
virtual int DumpExtensions(bool=0)
virtual XrdCryptoX509data Opaque()
virtual void Dump()
virtual XrdCryptoRSA * PKI()
virtual time_t NotBefore()
const char * SubjectHash()
virtual XrdSutBucket * Export()
virtual bool IsExpired(int when=0)
virtual const char * Issuer()
virtual kXR_int64 SerialNumber()
static bool MatchHostnames(const char *match_pattern, const char *fqdn)
virtual bool IsValid(int when=0)
virtual const char * ParentFile()
virtual time_t NotAfter()
virtual XrdOucString SerialNumberString()
const char * c_str() const
int erasefromstart(int sz=0)
int matches(const char *s, char wch=' *')
int length() const
int tokenize(XrdOucString &tok, int from, char del=':')
void lower(int pos, int size=0)