timestamp

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 29, 2021 License: MIT Imports: 15 Imported by: 0

README

go-timestamp

This library generates time stamping requests to TSA servers, and fetches the responses.

By default, the received token is verified against the system trust store.

Install

go get github.com/shizhMSFT/go-timestamp

Example

package main

import (
	"context"
	"fmt"
	"log"

	_ "crypto/sha256"

	"github.com/opencontainers/go-digest"
	"github.com/shizhMSFT/go-timestamp"
)

func main() {
	req, err := timestamp.NewRequest(digest.FromString("hello"))
	if err != nil {
		log.Fatal(err)
	}
	req.CertReq = true

	ts := timestamp.NewHTTPTimestamper(nil, "http://timestamp.sectigo.com")
	resp, err := ts.Timestamp(context.Background(), req)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println("status:", resp.Status.Status)
	info, err := resp.TimeStampTokenInfo()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("time:", info.GenTime)
	fmt.Println("serial:", info.SerialNumber)
}

Output:

status: 0
time: 2021-07-29 11:07:04 +0000 UTC
serial: 830360054253615705123898671080818616295644417367

Documentation

Index

Constants

View Source
const (
	PKIFailureInfoBadAlg              = 0  // unrecognized or unsupported Algorithm Identifier
	PKIFailureInfoBadRequest          = 2  // transaction not permitted or supported
	PKIFailureInfoBadDataFormat       = 5  // the data submitted has the wrong format
	PKIFailureInfoTimeNotAvailable    = 14 // the TSA's time source is not available
	PKIFailureInfoUnacceptedPolicy    = 15 // the requested TSA policy is not supported by the TSA.
	PKIFailureInfoUnacceptedExtension = 16 // the requested extension is not supported by the TSA.
	PKIFailureInfoAddInfoNotAvailable = 17 // the additional information requested could not be understood or is not available
	PKIFailureInfoSystemFailure       = 25 // the request cannot be handled due to system failure
)

Variables

View Source
var (
	OIDDigestAlgorithmSHA1   = asn1.ObjectIdentifier{1, 3, 14, 3, 2, 26}
	OIDDigestAlgorithmSHA256 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 1}
	OIDDigestAlgorithmSHA384 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 2}
	OIDDigestAlgorithmSHA512 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 3}
)
View Source
var (
	OIDSignatureAlgorithmRSA       = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}
	OIDSignatureAlgorithmRSASHA1   = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}
	OIDSignatureAlgorithmRSASHA256 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 11}
	OIDSignatureAlgorithmRSASHA384 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 12}
	OIDSignatureAlgorithmRSASHA512 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 13}

	OIDSignatureAlgorithmECDSASHA1   = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 1}
	OIDSignatureAlgorithmECDSASHA256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 2}
	OIDSignatureAlgorithmECDSASHA384 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 3}
	OIDSignatureAlgorithmECDSASHA512 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 4}
)
View Source
var (
	OIDAttributeContentType   = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 3}
	OIDAttributeMessageDigest = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 4}
	OIDAttributeSigningTime   = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 5}
)
View Source
var (
	OIDSignedData = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 2}
	OIDCTTSTInfo  = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 16, 1, 4}
)
View Source
var DigestAlgorithmOIDs = map[digest.Algorithm]asn1.ObjectIdentifier{
	digest.SHA256: OIDDigestAlgorithmSHA256,
	digest.SHA384: OIDDigestAlgorithmSHA384,
	digest.SHA512: OIDDigestAlgorithmSHA512,
}
View Source
var ErrMissingAttribute = errors.New("missing signer attribute")

Functions

func ComputeHash

func ComputeHash(hash crypto.Hash, message []byte) ([]byte, error)

func ConvertToHash

func ConvertToHash(digestAlgorithm asn1.ObjectIdentifier) (crypto.Hash, bool)

ConvertToHash converts digest algorithm in OID to golang crypto hash if it is available.

func ConvertToSignatureAlgorithm

func ConvertToSignatureAlgorithm(digestAlgorithm, signatureAlgorithm asn1.ObjectIdentifier) x509.SignatureAlgorithm

ConvertToSignatureAlgorithm converts algorithms encoded in ASN.1 to golang signature algorithm.

Types

type Accuracy

type Accuracy struct {
	Seconds      int `asn1:"optional"`
	Milliseconds int `asn1:"optional,tag:0"`
	Microseconds int `asn1:"optional,tag:1"`
}
Accuracy ::= SEQUENCE {
    seconds        INTEGER              OPTIONAL,
    millis     [0] INTEGER  (1..999)    OPTIONAL,
    micros     [1] INTEGER  (1..999)    OPTIONAL  }

type Attribute

type Attribute struct {
	Type   asn1.ObjectIdentifier
	Values asn1.RawValue `asn1:"set"`
}
Attribute ::= SEQUENCE {
  attrType OBJECT IDENTIFIER,
  attrValues SET OF AttributeValue }

type ContentInfo

type ContentInfo struct {
	ContentType asn1.ObjectIdentifier
	Content     asn1.RawValue `asn1:"explicit,tag:0"`
}
ContentInfo ::= SEQUENCE {
  contentType ContentType,
  content [0] EXPLICIT ANY DEFINED BY contentType }

type EncapsulatedContentInfo

type EncapsulatedContentInfo struct {
	ContentType asn1.ObjectIdentifier
	Content     []byte `asn1:"explicit,optional,tag:0"`
}
EncapsulatedContentInfo ::= SEQUENCE {
  eContentType ContentType,
  eContent [0] EXPLICIT OCTET STRING OPTIONAL }

type IssuerAndSerialNumber

type IssuerAndSerialNumber struct {
	Issuer       asn1.RawValue
	SerialNumber *big.Int
}
IssuerAndSerialNumber ::= SEQUENCE {
  issuer Name,
  serialNumber CertificateSerialNumber }

type MessageImprint

type MessageImprint struct {
	HashAlgorithm pkix.AlgorithmIdentifier
	HashedMessage []byte
}

MessageImprint contains the hash of the datum to be time-stamped.

MessageImprint ::= SEQUENCE  {
    hashAlgorithm                AlgorithmIdentifier,
    hashedMessage                OCTET STRING  }

type PKIFailureInfo

type PKIFailureInfo asn1.BitString

PKIFailureInfo contains error messages

type PKIStatus

type PKIStatus int

Status contains the PKI status code.

const (
	PKIStatusGranted PKIStatus = iota
	PKIStatusGrantedWithMods
	PKIStatusRejection
	PKIStatusWaiting
	PKIStatusRevocationWarning
	PKIStatusRevocationNotification
)

type PKIStatusInfo

type PKIStatusInfo struct {
	Status       PKIStatus
	StatusString string         `asn1:"optional"`
	FailInfo     PKIFailureInfo `asn1:"optional"`
}

PKIStatusInfo contains status codes and failure information for PKI messages.

PKIStatusInfo ::= SEQUENCE {
    status        PKIStatus,
    statusString  PKIFreeText     OPTIONAL,
    failInfo      PKIFailureInfo  OPTIONAL  }

type ParsedSignedData

type ParsedSignedData struct {
	Content      []byte
	ContentType  asn1.ObjectIdentifier
	Certificates []*x509.Certificate
	CRLs         []pkix.CertificateList
	// contains filtered or unexported fields
}

ParsedSignedData is ready to be read and verified.

func ParseSignedData

func ParseSignedData(data []byte) (*ParsedSignedData, error)

func (*ParsedSignedData) Verify

func (d *ParsedSignedData) Verify(roots *x509.CertPool) error

type Request

type Request struct {
	Version        int // currently v1
	MessageImprint MessageImprint
	ReqPolicy      TSAPolicyID      `asn1:"optional"`
	Nonce          *big.Int         `asn1:"optional"`
	CertReq        bool             `asn1:"optional,default:false"`
	Extensions     []pkix.Extension `asn1:"optional,tag:0"`
}

Request is a time-stamping request.

TimeStampReq ::= SEQUENCE  {
    version                      INTEGER  { v1(1) },
    messageImprint               MessageImprint,
      --a hash algorithm OID and the hash value of the data to be
      --time-stamped
    reqPolicy             TSAPolicyID              OPTIONAL,
    nonce                 INTEGER                  OPTIONAL,
    certReq               BOOLEAN                  DEFAULT FALSE,
    extensions            [0] IMPLICIT Extensions  OPTIONAL  }

func NewRequest

func NewRequest(digest digest.Digest) (*Request, error)

NewRequest creates a request based on the given digest.

func (*Request) MarshalBinary

func (r *Request) MarshalBinary() ([]byte, error)

func (*Request) UnmarshalBinary

func (r *Request) UnmarshalBinary(data []byte) error

type Response

type Response struct {
	Status         PKIStatusInfo
	TimeStampToken asn1.RawValue `asn1:"optional"`
}

Response is a time-stamping response.

TimeStampResp ::= SEQUENCE  {
    status                  PKIStatusInfo,
    timeStampToken          TimeStampToken     OPTIONAL  }

func (*Response) MarshalBinary

func (r *Response) MarshalBinary() ([]byte, error)

func (*Response) SignedData

func (r *Response) SignedData() (*ParsedSignedData, error)

func (*Response) TimeStampTokenInfo

func (r *Response) TimeStampTokenInfo() (*TSTInfo, error)

func (*Response) UnmarshalBinary

func (r *Response) UnmarshalBinary(data []byte) error

type SignedData

type SignedData struct {
	Version                    int
	DigestAlgorithmIdentifiers []pkix.AlgorithmIdentifier `asn1:"set"`
	EncapsulatedContentInfo    EncapsulatedContentInfo
	Certificates               asn1.RawValue          `asn1:"optional,tag:0"`
	CRLs                       []pkix.CertificateList `asn1:"optional,tag:1"`
	SignerInfos                []SignerInfo           `asn1:"set"`
}
SignedData ::= SEQUENCE {
  version CMSVersion,
  digestAlgorithms DigestAlgorithmIdentifiers,
  encapContentInfo EncapsulatedContentInfo,
  certificates [0] IMPLICIT CertificateSet OPTIONAL,
  crls [1] IMPLICIT CertificateRevocationLists OPTIONAL,
  signerInfos SignerInfos }

type SignerInfo

type SignerInfo struct {
	Version            int
	SignerIdentifier   IssuerAndSerialNumber
	DigestAlgorithm    pkix.AlgorithmIdentifier
	SignedAttributes   []Attribute `asn1:"optional,tag:0"`
	SignatureAlgorithm pkix.AlgorithmIdentifier
	Signature          []byte
	UnsignedAttributes []Attribute `asn1:"optional,tag:1"`
}
SignerInfo ::= SEQUENCE {
  version CMSVersion,
  sid SignerIdentifier,
  digestAlgorithm DigestAlgorithmIdentifier,
  signedAttrs [0] IMPLICIT SignedAttributes OPTIONAL,
  signatureAlgorithm SignatureAlgorithmIdentifier,
  signature SignatureValue,
  unsignedAttrs [1] IMPLICIT UnsignedAttributes OPTIONAL }

type TSAPolicyID

type TSAPolicyID = asn1.ObjectIdentifier

TSAPolicyID indicates the TSA policy.

type TSTInfo

type TSTInfo struct {
	Version        int
	Policy         TSAPolicyID
	MessageImprint MessageImprint
	SerialNumber   *big.Int
	GenTime        time.Time        `asn1:"generalized"`
	Accuracy       Accuracy         `asn1:"optional"`
	Ordering       bool             `asn1:"optional,default:false"`
	Nonce          *big.Int         `asn1:"optional"`
	TSA            asn1.RawValue    `asn1:"optional,tag:0"`
	Extensions     []pkix.Extension `asn1:"optional,tag:1"`
}
TSTInfo ::= SEQUENCE  {
    version                      INTEGER  { v1(1) },
    policy                       TSAPolicyId,
    messageImprint               MessageImprint,
      -- MUST have the same value as the similar field in
      -- TimeStampReq
    serialNumber                 INTEGER,
     -- Time-Stamping users MUST be ready to accommodate integers
     -- up to 160 bits.
    genTime                      GeneralizedTime,
    accuracy                     Accuracy                 OPTIONAL,
    ordering                     BOOLEAN             DEFAULT FALSE,
    nonce                        INTEGER                  OPTIONAL,
      -- MUST be present if the similar field was present
      -- in TimeStampReq.  In that case it MUST have the same value.
    tsa                          [0] GeneralName          OPTIONAL,
    extensions                   [1] IMPLICIT Extensions  OPTIONAL   }

type Timestamper

type Timestamper interface {
	Timestamp(context.Context, *Request) (*Response, error)
}

Timestamper stamps the time

func NewHTTPTimestamper

func NewHTTPTimestamper(rt http.RoundTripper, endpoint string) Timestamper

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL