github.com/clocklock/go-rfc3161@v0.0.0-20160419203229-5ea544d9dee0/response.go (about)

     1  package rfc3161
     2  
     3  import (
     4  	"bytes"
     5  	"crypto/rsa"
     6  	"crypto/x509"
     7  	"crypto/x509/pkix"
     8  	"encoding/asn1"
     9  	"errors"
    10  	"io/ioutil"
    11  	"math/big"
    12  	"time"
    13  
    14  	"github.com/phayes/cryptoid"
    15  
    16  	_ "crypto/sha1"   // Link in all possible supported hash algorithms
    17  	_ "crypto/sha256" // Link in all possible supported hash algorithms
    18  	_ "crypto/sha512" // Link in all possible supported hash algorithms
    19  
    20  	_ "golang.org/x/crypto/sha3" // Link in all possible supported hash algorithms
    21  )
    22  
    23  // Errors
    24  var (
    25  	ErrIncorrectNonce              = errors.New("rfc3161: response: Response has incorrect nonce")
    26  	ErrNoTST                       = errors.New("rfc3161: response: Response does not contain TSTInfo")
    27  	ErrNoCertificate               = errors.New("rfc3161: response: No certificates provided")
    28  	ErrNoCertificateValid          = errors.New("rfc3161: response: No certificates provided signs the given TSTInfo")
    29  	ErrMismatchedCertificates      = errors.New("rfc3161: response: Mismatched certificates")
    30  	ErrCertificateKeyUsage         = errors.New("rfc3161: response: certificate: Invalid KeyUsage field")
    31  	ErrCertificateExtKeyUsageUsage = errors.New("rfc3161: response: certificate: Invalid ExtKeyUsage field")
    32  	ErrCertificateExtension        = errors.New("rfc3161: response: certificate: Missing critical timestamping extension")
    33  	ErrInvalidSignatureDigestAlgo  = errors.New("rfc3161: response: Invalid signature digest algorithm")
    34  	ErrUnsupportedSignerInfos      = errors.New("rfc3161: response: package only supports responses with a single SignerInfo")
    35  	ErrUnableToParseSID            = errors.New("rfc3161: response: Unable to parse SignerInfo.sid")
    36  	ErrVerificationError           = errors.New("rfc3161: response: Verfication error")
    37  	ErrInvalidOID                  = errors.New("rfc3161: response: Invalid OID")
    38  )
    39  
    40  // TimeStampResp contains a full Time Stamp Response as defined by RFC 3161
    41  // It is also known as a "Time Stamp Reply"
    42  // When stored into a file it should contain the extension ".tsr"
    43  // It has a mime-type of "application/timestamp-reply"
    44  type TimeStampResp struct {
    45  	Status         PKIStatusInfo
    46  	TimeStampToken `asn1:"optional"`
    47  }
    48  
    49  // ReadTSR reads a .tsr file into a TimeStampResp
    50  func ReadTSR(filename string) (*TimeStampResp, error) {
    51  	der, err := ioutil.ReadFile(filename)
    52  	if err != nil {
    53  		return nil, err
    54  	}
    55  	resp := new(TimeStampResp)
    56  	rest, err := asn1.Unmarshal(der, resp)
    57  	if err != nil {
    58  		return nil, err
    59  	}
    60  	if len(rest) != 0 {
    61  		return resp, ErrUnrecognizedData
    62  	}
    63  	return resp, nil
    64  }
    65  
    66  // Verify does a full verification of the Time Stamp Response
    67  // including cryptographic verification of the signature
    68  //
    69  // If req.CertReq was set to true, cert may be set to nil and it will be loaded
    70  // from the response automatically
    71  //
    72  // WARNING: Does not do any revocation checking
    73  func (resp *TimeStampResp) Verify(req *TimeStampReq, cert *x509.Certificate) error {
    74  	tst, err := resp.GetTSTInfo()
    75  	if err != nil {
    76  		return err
    77  	}
    78  
    79  	// Verify the request for sanity's sake
    80  	err = req.Verify()
    81  	if err != nil {
    82  		return err
    83  	}
    84  
    85  	// Verify the status
    86  	if resp.Status.Status.IsError() {
    87  		return &resp.Status
    88  	}
    89  
    90  	// Verify the nonce
    91  	if req.Nonce == nil || tst.Nonce == nil {
    92  		if tst.Nonce != tst.Nonce {
    93  			return ErrIncorrectNonce
    94  		}
    95  	} else if req.Nonce.Cmp(tst.Nonce) != 0 {
    96  		return ErrIncorrectNonce
    97  	}
    98  
    99  	// Verify that the OIDs are correct
   100  	if !resp.ContentType.Equal(OidSignedData) || !resp.EContentType.Equal(OidContentTypeTSTInfo) {
   101  		return ErrInvalidOID
   102  	}
   103  
   104  	// Get the certificate
   105  	respcert, err := resp.GetSigningCert()
   106  	if err != nil {
   107  		return err
   108  	}
   109  	// Rationalize the passed-in certificate vis-a-vis certificate in the response
   110  	if req.CertReq {
   111  		if respcert != nil && cert != nil {
   112  			if !bytes.Equal(cert.Raw, respcert.Raw) {
   113  				return ErrMismatchedCertificates
   114  			}
   115  		} else if cert == nil {
   116  			cert = respcert
   117  		}
   118  	}
   119  	if cert == nil {
   120  		return ErrNoCertificate
   121  	}
   122  
   123  	// Get any intermediates that might be needed
   124  	intermediates, err := resp.GetCertificates()
   125  	if err != nil && err != ErrNoCertificate {
   126  		return err
   127  	}
   128  	interpool := x509.NewCertPool()
   129  	for _, intercert := range intermediates {
   130  		interpool.AddCert(intercert)
   131  	}
   132  
   133  	// Verify the certificate
   134  	err = resp.VerifyCertificate(cert, interpool)
   135  	if err != nil {
   136  		return err
   137  	}
   138  
   139  	// Verify the signature
   140  	err = resp.VerifySignature(cert)
   141  	if err != nil {
   142  		return err
   143  	}
   144  
   145  	// TODO: Review RFC3161 for other checks that are needed
   146  
   147  	// All checks pass
   148  	return nil
   149  }
   150  
   151  // VerifyCertificate verifies that the certificate was set up correctly for key signing,
   152  // is proprely referenced within the reponse, and has a valid signature chain.
   153  //
   154  // intermediates is any intermediate certificates needed to verify the cert. Can be nil.
   155  //
   156  // WARNING: Does not do any revocation checking
   157  func (resp *TimeStampResp) VerifyCertificate(cert *x509.Certificate, intermediates *x509.CertPool) error {
   158  	if cert == nil {
   159  		return ErrNoCertificate
   160  	}
   161  
   162  	// Key usage must contain the KeyUsageDigitalSignature bit
   163  	// and MAY contain the non-repudiation / content-commitment bit
   164  	if cert.KeyUsage != x509.KeyUsageDigitalSignature && cert.KeyUsage != (x509.KeyUsageDigitalSignature+x509.KeyUsageContentCommitment) {
   165  		return ErrCertificateKeyUsage
   166  	}
   167  
   168  	// Next check the extended key usage
   169  	// Only one ExtKeyUsage may be defined as per RFC 3161
   170  	if len(cert.ExtKeyUsage) != 1 {
   171  		return ErrCertificateExtKeyUsageUsage
   172  	}
   173  	if cert.ExtKeyUsage[0] != x509.ExtKeyUsageTimeStamping {
   174  		return ErrCertificateExtKeyUsageUsage
   175  	}
   176  
   177  	// Check to make sure it has the correct extension
   178  	// Only one Extended Key Usage may be defined, it must be critical,
   179  	// and it must be OidExtKeyUsageTimeStamping
   180  	for _, ext := range cert.Extensions {
   181  		if ext.Id.Equal(OidExtKeyUsage) {
   182  			if !ext.Critical {
   183  				return ErrCertificateExtKeyUsageUsage
   184  			}
   185  			var rfc3161Ext []asn1.ObjectIdentifier
   186  			_, err := asn1.Unmarshal(ext.Value, &rfc3161Ext)
   187  			if err != nil {
   188  				return err
   189  			}
   190  			if len(rfc3161Ext) != 1 {
   191  				return ErrCertificateExtKeyUsageUsage
   192  			}
   193  			if !rfc3161Ext[0].Equal(OidExtKeyUsageTimeStamping) {
   194  				return ErrCertificateExtKeyUsageUsage
   195  			}
   196  		}
   197  	}
   198  
   199  	// Verify the certificate chain
   200  	opts := x509.VerifyOptions{
   201  		KeyUsages:     []x509.ExtKeyUsage{x509.ExtKeyUsageTimeStamping},
   202  		Roots:         RootCerts,
   203  		Intermediates: intermediates,
   204  	}
   205  	_, err := cert.Verify(opts)
   206  	if err != nil {
   207  		return err
   208  	}
   209  
   210  	return nil
   211  }
   212  
   213  // TimeStampToken is a wrapper than contains the OID for a TimeStampToken
   214  // as well as the wrapped SignedData
   215  type TimeStampToken struct {
   216  	ContentType asn1.ObjectIdentifier // MUST BE OidSignedData
   217  	SignedData  `asn1:"tag:0,explicit,optional"`
   218  }
   219  
   220  // SignedData is a shared-standard as defined by RFC 2630
   221  type SignedData struct {
   222  	Version          int                        `asn1:"default:4"`
   223  	DigestAlgorithms []pkix.AlgorithmIdentifier `asn1:"set"`
   224  	EncapsulatedContentInfo
   225  	Certificates asn1.RawValue          `asn1:"optional,set,tag:0"` // Certificate DER. Use GetCertificates() to get the x509.Certificate list
   226  	CRLs         []pkix.CertificateList `asn1:"optional,tag:1"`
   227  	SignerInfos  []SignerInfo           `asn1:"set"`
   228  }
   229  
   230  // GetSigningCert gets the signer and the associated certificate
   231  // The certificate may be nil if the request did not ask for it
   232  func (sd *SignedData) GetSigningCert() (*x509.Certificate, error) {
   233  	// Get the signerInfo
   234  	if len(sd.SignerInfos) != 1 {
   235  		return nil, ErrUnsupportedSignerInfos
   236  	}
   237  	signer := sd.SignerInfos[0]
   238  	id, err := signer.GetSID()
   239  	if err != nil {
   240  		return nil, err
   241  	}
   242  
   243  	var cert *x509.Certificate
   244  	if len(sd.Certificates.Bytes) != 0 {
   245  		certs, err := x509.ParseCertificates(sd.Certificates.Bytes)
   246  		if err != nil {
   247  			return nil, err
   248  		}
   249  		for _, checkcert := range certs {
   250  			switch sid := id.(type) {
   251  			case *IssuerAndSerialNumber:
   252  				if checkcert.SerialNumber.Cmp(sid.SerialNumber) == 0 {
   253  					cert = checkcert
   254  					break
   255  				}
   256  			case []byte:
   257  				if bytes.Equal(checkcert.SubjectKeyId, sid) {
   258  					cert = checkcert
   259  					break
   260  				}
   261  			default:
   262  				return nil, ErrUnableToParseSID
   263  			}
   264  		}
   265  	}
   266  	return cert, nil
   267  }
   268  
   269  // VerifySignature verifies that the given certificate signed the TSTInfo
   270  func (sd *SignedData) VerifySignature(cert *x509.Certificate) error {
   271  	// Get the signerInfo
   272  	if len(sd.SignerInfos) != 1 {
   273  		return ErrUnsupportedSignerInfos
   274  	}
   275  	signer := sd.SignerInfos[0]
   276  
   277  	hashAlgo, err := cryptoid.HashAlgorithmByOID(signer.DigestAlgorithm.Algorithm.String())
   278  	if err != nil {
   279  		return err
   280  	}
   281  
   282  	// Marshal the Signed Attributes
   283  	derbytes, err := asn1.Marshal(signer.SignedAttrs)
   284  	if err != nil {
   285  		return err
   286  	}
   287  
   288  	// Hack the DER bytes of the Signed Attributes to be EXPLICIT SET
   289  	derbytes[0] = 0x31
   290  	derbytes[1] = 0x81
   291  
   292  	// Hash the DER bytes
   293  	hash := hashAlgo.Hash.New()
   294  	hash.Write(derbytes)
   295  	digest := hash.Sum(nil)
   296  
   297  	// Unpack the public key
   298  	pub := cert.PublicKey.(*rsa.PublicKey)
   299  
   300  	// Verify the signature
   301  	err = rsa.VerifyPKCS1v15(pub, hashAlgo.Hash, digest, signer.Signature)
   302  	if err != nil {
   303  		return ErrVerificationError
   304  	}
   305  
   306  	// Verify the signed attributes
   307  	// This will check the following:
   308  	// - the content-type is of the type TSTInfo
   309  	// - the message-digest corresponds to TSTInfo
   310  	// - there is exactly one digest attribute and one content-type attribute
   311  	var digestOK, contentOK bool
   312  	var count int
   313  	for _, attr := range signer.SignedAttrs {
   314  		if attr.Type.Equal(OidContentType) {
   315  			count++
   316  			oiddata, _ := asn1.Marshal(OidContentTypeTSTInfo)
   317  			if bytes.Equal(oiddata, attr.Value.Bytes) {
   318  				contentOK = true
   319  			}
   320  		}
   321  		if attr.Type.Equal(OidMessageDigest) {
   322  			count++
   323  			hash := hashAlgo.Hash.New()
   324  			hash.Write(sd.EContent)
   325  			digest := hash.Sum(nil)
   326  			if bytes.Equal(digest, attr.Value.Bytes[2:]) {
   327  				digestOK = true
   328  			}
   329  		}
   330  	}
   331  	if !digestOK || !contentOK || count != 2 {
   332  		return ErrVerificationError
   333  	}
   334  
   335  	// Everything is OK
   336  	return nil
   337  }
   338  
   339  // GetCertificates gets a list of x509.Certificate objects from the DER encoded Certificates field
   340  func (sd *SignedData) GetCertificates() ([]*x509.Certificate, error) {
   341  	if len(sd.Certificates.Bytes) == 0 {
   342  		return nil, ErrNoCertificate
   343  	}
   344  	return x509.ParseCertificates(sd.Certificates.Bytes)
   345  }
   346  
   347  // SignerInfo is a shared-standard as defined by RFC 2630
   348  type SignerInfo struct {
   349  	Version            int           `asn1:"default:1"`
   350  	SID                asn1.RawValue // CHOICE. See SignerInfo.GetSID()
   351  	DigestAlgorithm    pkix.AlgorithmIdentifier
   352  	SignedAttrs        []Attribute `asn1:"tag:0"`
   353  	SignatureAlgorithm pkix.AlgorithmIdentifier
   354  	Signature          []byte
   355  	UnsignedAtrributes []Attribute `asn1:"optional,tag:1"`
   356  }
   357  
   358  // GetSID Gets the certificate identifier
   359  // It returns an interface that could be one of:
   360  //  - *rfc3161.IssuerAndSerialNumber
   361  //  - []byte if the identifier is a SubjectKeyId
   362  func (sd *SignerInfo) GetSID() (interface{}, error) {
   363  	var sid interface{}
   364  	switch sd.Version {
   365  	case 1:
   366  		sid = &IssuerAndSerialNumber{}
   367  	case 3:
   368  		sid = []byte{}
   369  	default:
   370  		return nil, errors.New("Invalid SignerInfo.SID")
   371  	}
   372  
   373  	_, err := asn1.Unmarshal(sd.SID.FullBytes, sid)
   374  	if err != nil {
   375  		return nil, err
   376  	}
   377  	return sid, nil
   378  }
   379  
   380  // IssuerAndSerialNumber is defined in RFC 2630
   381  type IssuerAndSerialNumber struct {
   382  	IssuerName   pkix.RDNSequence
   383  	SerialNumber *big.Int
   384  }
   385  
   386  // Attribute is defined in RFC 2630
   387  // The fields of type SignedAttribute and UnsignedAttribute have the
   388  // following meanings:
   389  //
   390  //   Type indicates the type of attribute.  It is an object
   391  //   identifier.
   392  //
   393  //   Value is a set of values that comprise the attribute.  The
   394  //   type of each value in the set can be determined uniquely by
   395  //   Type.
   396  type Attribute struct {
   397  	Type  asn1.ObjectIdentifier
   398  	Value asn1.RawValue
   399  }
   400  
   401  // EncapsulatedContentInfo is defined in RFC 2630
   402  //
   403  // The fields of type EncapsulatedContentInfo of the SignedData
   404  // construct have the following meanings:
   405  //
   406  // eContentType is an object identifier that uniquely specifies the
   407  // content type.  For a time-stamp token it is defined as:
   408  //
   409  // id-ct-TSTInfo  OBJECT IDENTIFIER ::= { iso(1) member-body(2)
   410  // us(840) rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) ct(1) 4}
   411  //
   412  // eContent is the content itself, carried as an octet string.
   413  // The eContent SHALL be the DER-encoded value of TSTInfo.
   414  //
   415  // The time-stamp token MUST NOT contain any signatures other than the
   416  // signature of the TSA.  The certificate identifier (ESSCertID) of the
   417  // TSA certificate MUST be included as a signerInfo attribute inside a
   418  // SigningCertificate attribute.
   419  type EncapsulatedContentInfo struct {
   420  	EContentType asn1.ObjectIdentifier // MUST BE OidContentTypeTSTInfo
   421  	EContent     asn1.RawContent       `asn1:"explicit,optional,tag:0"` // DER encoding of TSTInfo
   422  }
   423  
   424  // GetTSTInfo unpacks the DER encoded TSTInfo
   425  func (eci *EncapsulatedContentInfo) GetTSTInfo() (*TSTInfo, error) {
   426  	if len(eci.EContent) == 0 {
   427  		return nil, ErrNoTST
   428  	}
   429  
   430  	tstinfo := new(TSTInfo)
   431  	rest, err := asn1.Unmarshal(eci.EContent, tstinfo)
   432  	if err != nil {
   433  		return nil, err
   434  	}
   435  	if len(rest) != 0 {
   436  		return tstinfo, ErrUnrecognizedData
   437  	}
   438  
   439  	return tstinfo, nil
   440  }
   441  
   442  // TSTInfo is the acutal DER signed data and represents the core of the Time Stamp Reponse.
   443  // It contains the time-stamp, the accuracy, and all other pertinent informatuon
   444  type TSTInfo struct {
   445  	Version        int                   `json:"version" asn1:"default:1"`
   446  	Policy         asn1.ObjectIdentifier `json:"policy"`                           // Identifier for the policy. For many TSA's, often the same as SignedData.DigestAlgorithm
   447  	MessageImprint MessageImprint        `json:"message-imprint"`                  // MUST have the same value of MessageImprint in matching TimeStampReq
   448  	SerialNumber   *big.Int              `json:"serial-number"`                    // Time-Stamping users MUST be ready to accommodate integers up to 160 bits
   449  	GenTime        time.Time             `json:"gen-time"`                         // The time at which it was stamped
   450  	Accuracy       Accuracy              `json:"accuracy" asn1:"optional"`         // Accuracy represents the time deviation around the UTC time.
   451  	Ordering       bool                  `json:"ordering" asn1:"optional"`         // True if SerialNumber increases monotonically with time.
   452  	Nonce          *big.Int              `json:"nonce" asn1:"optional"`            // MUST be present if the similar field was present in TimeStampReq.  In that case it MUST have the same value.
   453  	TSA            asn1.RawValue         `json:"tsa" asn1:"optional,tag:0"`        // This is a CHOICE (See RFC 3280 for all choices). See https://github.com/golang/go/issues/13999 for information on handling.
   454  	Extensions     []pkix.Extension      `json:"extensions" asn1:"optional,tag:1"` // List of extensions
   455  }
   456  
   457  // Accuracy represents the time deviation around the UTC time.
   458  //
   459  // If either seconds, millis or micros is missing, then a value of zero
   460  // MUST be taken for the missing field.
   461  //
   462  // By adding the accuracy value to the GeneralizedTime, an upper limit
   463  // of the time at which the time-stamp token has been created by the TSA
   464  // can be obtained.  In the same way, by subtracting the accuracy to the
   465  // GeneralizedTime, a lower limit of the time at which the time-stamp
   466  // token has been created by the TSA can be obtained.
   467  //
   468  // Accuracy can be decomposed in seconds, milliseconds (between 1-999)
   469  // and microseconds (1-999), all expressed as integer.
   470  //
   471  // When the accuracy field is not present, then the accuracy
   472  // may be available through other means, e.g., the TSAPolicyId.
   473  type Accuracy struct {
   474  	Seconds int `asn1:"optional"`
   475  	Millis  int `asn1:"optional,tag:0"`
   476  	Micros  int `asn1:"optional,tag:1"`
   477  }
   478  
   479  // Duration gets the time.Duration representation of the Accuracy
   480  func (acc *Accuracy) Duration() time.Duration {
   481  	return (time.Duration(acc.Seconds) * time.Second) + (time.Duration(acc.Millis) * time.Millisecond) + (time.Duration(acc.Micros) * time.Microsecond)
   482  }