XRootD
XrdSecgsiRtag.hh
Go to the documentation of this file.
1 #ifndef __XRD_GSIRTAG_H__
2 #define __XRD_GSIRTAG_H__
3 /******************************************************************************/
4 /* */
5 /* X r d S e c g s i R t a g . h h */
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 /******************************************************************************/
27 
28 #include <cstring>
29 
32 
33 /******************************************************************************/
34 /* */
35 /* Helpers for the GSI random tag (kXRS_rtag). */
36 /* */
37 /* A peer signs the random tag of the other side with its private key to */
38 /* prove that it owns the key. The signature uses RSA with PKCS#1 v1.5 */
39 /* padding and no digest, so the signed value must never be under the */
40 /* control of the peer. Two rules keep it safe: */
41 /* */
42 /* 1. Sign only a well formed random tag: exactly 8 bytes of 7-bit ASCII. */
43 /* Every ASN.1 DigestInfo is at least 34 bytes long, and no hash in use */
44 /* with RSA has an 8 byte output, so the length check alone excludes */
45 /* them. The byte range accepts all known generators: XrdSutRndm uses */
46 /* [a-zA-Z0-9./], and dCache (xrootd4j) uses bytes 0x00 to 0x7e. */
47 /* This rule applies to every peer, whatever version it claims. */
48 /* */
49 /* 2. From version XrdSecgsiVersRtagHash on, sign the context bound digest */
50 /* of the tag instead of the tag itself. The digest is a bare hash, not */
51 /* a DigestInfo, so no PKCS#1 v1.5 verifier accepts a signature over it. */
52 /* */
53 /******************************************************************************/
54 
55 //
56 // Length of a GSI random tag, see XrdSutRndm::GetRndmTag()
57 #define kXRSrtagLen 8
58 
59 //
60 // Context prefix for the digest of the random tag
61 #define kXRSrtagCtx "XRD-GSI-RTAG-v1"
62 
63 //
64 // Digest used for the random tag; SHA-256 gives 32 bytes
65 #define kXRSrtagMD "sha256"
66 
67 //
68 // Buffer size that holds the digest of a random tag (EVP_MAX_MD_SIZE)
69 #define kXRSrtagMDMax 64
70 
71 //_____________________________________________________________________________
72 inline bool XrdSecgsiRtagIsValid(const char *rtag, int len)
73 {
74  // Return true if rtag holds a well formed GSI random tag, that is
75  // exactly kXRSrtagLen bytes of 7-bit ASCII. The length is what keeps
76  // the signature safe; the byte range follows the known generators.
77 
78  if (!rtag || len != kXRSrtagLen) return false;
79 
80  for (int i = 0; i < len; i++)
81  if (static_cast<unsigned char>(rtag[i]) > 0x7f) return false;
82 
83  return true;
84 }
85 
86 //_____________________________________________________________________________
87 inline int XrdSecgsiRtagDigest(XrdCryptoFactory *cf, const char *rtag, int len,
88  char *out, int outmax)
89 {
90  // Fill out with the context bound digest of rtag, that is
91  // SHA-256(kXRSrtagCtx || rtag). Return the number of bytes written,
92  // or -1 in case of error.
93 
94  if (!cf || !rtag || len <= 0 || !out) return -1;
95 
96  // The factory returns a valid and initialized digest, or null
98  if (!md) return -1;
99 
100  int lout = -1;
101 
102  if (md->Update(kXRSrtagCtx, (int)strlen(kXRSrtagCtx)) == 0 &&
103  md->Update(rtag, len) == 0 && md->Final() == 0 &&
104  md->Length() > 0 && md->Length() <= outmax) {
105  lout = md->Length();
106  memcpy(out, md->Buffer(), lout);
107  }
108 
109  delete md;
110 
111  return lout;
112 }
113 
114 #endif
#define kXRSrtagLen
#define kXRSrtagMD
int XrdSecgsiRtagDigest(XrdCryptoFactory *cf, const char *rtag, int len, char *out, int outmax)
#define kXRSrtagCtx
bool XrdSecgsiRtagIsValid(const char *rtag, int len)
virtual int Length() const
virtual char * Buffer() const
virtual XrdCryptoMsgDigest * MsgDigest(const char *dgst)
virtual int Update(const char *b, int l)