1 package crl 2 3 import ( 4 "encoding/json" 5 "math/big" 6 "time" 7 8 "github.com/letsencrypt/boulder/issuance" 9 ) 10 11 // number represents the 'crlNumber' field of a CRL. It must be constructed by 12 // calling `Number()`. 13 type number *big.Int 14 15 // Number derives the 'CRLNumber' field for a CRL from the value of the 16 // 'thisUpdate' field provided as a `time.Time`. 17 func Number(thisUpdate time.Time) number { 18 // Per RFC 5280 Section 5.2.3, 'CRLNumber' is a monotonically increasing 19 // sequence number for a given CRL scope and CRL that MUST be at most 20 20 // octets. A 64-bit (8-byte) integer will never exceed that requirement, but 21 // lets us guarantee that the CRL Number is always increasing without having 22 // to store or look up additional state. 23 return number(big.NewInt(thisUpdate.UnixNano())) 24 } 25 26 // id is a unique identifier for a CRL which is primarily used for logging. This 27 // identifier is composed of the 'Issuer', 'CRLNumber', and the shard index 28 // (e.g. {"issuerID": 123, "crlNum": 456, "shardIdx": 78}). It must be constructed 29 // by calling `Id()`. 30 type id string 31 32 // Id is a utility function which constructs a new `id`. 33 func Id(issuerID issuance.IssuerNameID, shardIdx int, crlNumber number) id { 34 type info struct { 35 IssuerID issuance.IssuerNameID `json:"issuerID"` 36 ShardIdx int `json:"shardIdx"` 37 CRLNumber number `json:"crlNumber"` 38 } 39 jsonBytes, err := json.Marshal(info{issuerID, shardIdx, crlNumber}) 40 if err != nil { 41 panic(err) 42 } 43 return id(jsonBytes) 44 } 45