go-hep.org/x/hep@v0.38.1/xrootd/xrdproto/sigver/sigver.go (about)

     1  // Copyright ©2018 The go-hep Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package sigver contains the structures describing sigver request.
     6  package sigver // import "go-hep.org/x/hep/xrootd/xrdproto/sigver"
     7  
     8  import (
     9  	"crypto/sha256"
    10  	"encoding/binary"
    11  
    12  	"go-hep.org/x/hep/xrootd/internal/xrdenc"
    13  	"go-hep.org/x/hep/xrootd/xrdproto/verifyw"
    14  	"go-hep.org/x/hep/xrootd/xrdproto/write"
    15  )
    16  
    17  // RequestID is the id of the request, it is sent as part of message.
    18  // See xrootd protocol specification for details: http://xrootd.org/doc/dev45/XRdv310.pdf, 2.3 Client Request Format.
    19  const RequestID uint16 = 3029
    20  
    21  // Flags are the request indicators.
    22  type Flags uint8
    23  
    24  const (
    25  	NoData Flags = 1 // NoData indicates whether the data payload is included in the hash.
    26  )
    27  
    28  // Request holds the sigver request parameters.
    29  type Request struct {
    30  	ID        uint16 // ID is the requestID of the subsequent request.
    31  	Version   byte   // Version is a version of the signature protocol to be used. Currently only the zero value is supported.
    32  	Flags     Flags  // Flags are the request indicators. Currently only NoData is supported which indicates whether the data payload is included in the hash.
    33  	SeqID     int64  // SeqID is a monotonically increasing sequence number. Each requests should have a sequence number that is greater than a previous one.
    34  	Crypto    byte   // Crypto identifies the cryptography used to construct the signature.
    35  	_         [3]byte
    36  	Signature []byte
    37  }
    38  
    39  // ReqID implements xrdproto.Request.ReqID.
    40  func (req *Request) ReqID() uint16 { return RequestID }
    41  
    42  // ShouldSign implements xrdproto.Request.ShouldSign.
    43  func (req *Request) ShouldSign() bool { return false }
    44  
    45  // MarshalXrd implements xrdproto.Marshaler.
    46  func (o Request) MarshalXrd(wBuffer *xrdenc.WBuffer) error {
    47  	wBuffer.WriteU16(o.ID)
    48  	wBuffer.WriteU8(o.Version)
    49  	wBuffer.WriteU8(uint8(o.Flags))
    50  	wBuffer.WriteI64(o.SeqID)
    51  	wBuffer.WriteU8(o.Crypto)
    52  	wBuffer.Next(3)
    53  	wBuffer.WriteLen(len(o.Signature))
    54  	wBuffer.WriteBytes(o.Signature)
    55  	return nil
    56  }
    57  
    58  // UnmarshalXrd implements xrdproto.Unmarshaler.
    59  func (o *Request) UnmarshalXrd(rBuffer *xrdenc.RBuffer) error {
    60  	o.ID = rBuffer.ReadU16()
    61  	o.Version = rBuffer.ReadU8()
    62  	o.Flags = Flags(rBuffer.ReadU8())
    63  	o.SeqID = rBuffer.ReadI64()
    64  	o.Crypto = rBuffer.ReadU8()
    65  	rBuffer.Skip(3)
    66  	o.Signature = make([]byte, rBuffer.ReadLen())
    67  	rBuffer.ReadBytes(o.Signature)
    68  	return nil
    69  }
    70  
    71  func NewRequest(requestID uint16, seqID int64, data []byte) Request {
    72  	hash := sha256.New()
    73  
    74  	var s [8]byte
    75  	binary.BigEndian.PutUint64(s[:], uint64(seqID))
    76  	_, _ = hash.Write(s[:])
    77  
    78  	if requestID == write.RequestID || requestID == verifyw.RequestID {
    79  		_, _ = hash.Write(data[:24])
    80  	} else {
    81  		_, _ = hash.Write(data)
    82  	}
    83  	signature := hash.Sum(nil)
    84  
    85  	var f Flags
    86  	if requestID == write.RequestID {
    87  		f |= NoData
    88  	}
    89  
    90  	return Request{ID: requestID, SeqID: seqID, Crypto: 0x01, Signature: signature[:], Flags: f}
    91  }