XRootD
Loading...
Searching...
No Matches
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. XrdSutRndm::GetRndmTag() always */
43/* produces 8 characters in [a-zA-Z0-9./], and every ASN.1 DigestInfo */
44/* is at least 34 bytes long, so the length check alone excludes them. */
45/* This rule applies to every peer, whatever version it claims. */
46/* */
47/* 2. From version XrdSecgsiVersRtagHash on, sign the context bound digest */
48/* of the tag instead of the tag itself. The digest is a bare hash, not */
49/* a DigestInfo, so no PKCS#1 v1.5 verifier accepts a signature over it. */
50/* */
51/******************************************************************************/
52
53//
54// Length of a GSI random tag, see XrdSutRndm::GetRndmTag()
55#define kXRSrtagLen 8
56
57//
58// Context prefix for the digest of the random tag
59#define kXRSrtagCtx "XRD-GSI-RTAG-v1"
60
61//
62// Digest used for the random tag; SHA-256 gives 32 bytes
63#define kXRSrtagMD "sha256"
64
65//
66// Buffer size that holds the digest of a random tag (EVP_MAX_MD_SIZE)
67#define kXRSrtagMDMax 64
68
69//_____________________________________________________________________________
70inline bool XrdSecgsiRtagIsValid(const char *rtag, int len)
71{
72 // Return true if rtag holds a well formed GSI random tag, that is
73 // exactly kXRSrtagLen characters in the set [a-zA-Z0-9./].
74
75 if (!rtag || len != kXRSrtagLen) return false;
76
77 for (int i = 0; i < len; i++) {
78 const char c = rtag[i];
79 if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
80 (c >= '0' && c <= '9') || c == '.' || c == '/') continue;
81 return false;
82 }
83
84 return true;
85}
86
87//_____________________________________________________________________________
88inline int XrdSecgsiRtagDigest(XrdCryptoFactory *cf, const char *rtag, int len,
89 char *out, int outmax)
90{
91 // Fill out with the context bound digest of rtag, that is
92 // SHA-256(kXRSrtagCtx || rtag). Return the number of bytes written,
93 // or -1 in case of error.
94
95 if (!cf || !rtag || len <= 0 || !out) return -1;
96
97 // The factory returns a valid and initialized digest, or null
99 if (!md) return -1;
100
101 int lout = -1;
102
103 if (md->Update(kXRSrtagCtx, (int)strlen(kXRSrtagCtx)) == 0 &&
104 md->Update(rtag, len) == 0 && md->Final() == 0 &&
105 md->Length() > 0 && md->Length() <= outmax) {
106 lout = md->Length();
107 memcpy(out, md->Buffer(), lout);
108 }
109
110 delete md;
111
112 return lout;
113}
114
115#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)