package datastructures import ( "bytes" "encoding/binary" "fmt" "time" "git.cacert.org/cacert-gosigner/shared" ) type SignerRequest struct { Version uint8 Action shared.Action System shared.CryptoSystemId Root shared.CryptoSystemRootId Profile shared.CertificateProfileId MdAlgorithm shared.MessageDigestAlgorithmId Days uint16 Spkac uint8 Content1 []byte Content2 []byte Content3 []byte } func SignerRequestFromData(blockData []byte) (*SignerRequest, error) { headerLength := Decode24BitLength(blockData[0:3]) headerBytes := blockData[3 : 3+headerLength] contentBytes := blockData[3+headerLength:] content1Length := Decode24BitLength(contentBytes[0:3]) content1 := contentBytes[3 : 3+content1Length] content2Offset := 3 + content1Length content2Length := Decode24BitLength(contentBytes[content2Offset : content2Offset+3]) content2 := contentBytes[3+content2Offset : 3+content2Offset+content2Length] content3Offset := 3 + content2Offset + content2Length content3Length := Decode24BitLength(contentBytes[content3Offset : content3Offset+3]) content3 := contentBytes[3+content3Offset : 3+content3Offset+content3Length] return &SignerRequest{ Version: headerBytes[0], Action: shared.Action(headerBytes[1]), System: shared.CryptoSystemId(headerBytes[2]), Root: shared.CryptoSystemRootId(headerBytes[3]), Profile: shared.CertificateProfileId(headerBytes[4]), MdAlgorithm: shared.MessageDigestAlgorithmId(headerBytes[5]), Days: binary.BigEndian.Uint16([]byte{headerBytes[6], headerBytes[7]}), Spkac: headerBytes[8], Content1: content1, Content2: content2, Content3: content3, }, nil } func (r *SignerRequest) Serialize() []byte { parameter2Bytes := make([]byte, 2) binary.BigEndian.PutUint16(parameter2Bytes, r.Days) headerBytes := bytes.Join([][]byte{ { r.Version, byte(r.Action), byte(r.System), byte(r.Root), byte(r.Profile), byte(r.MdAlgorithm), }, parameter2Bytes, {r.Spkac}}, []byte{}) content1Bytes := r.Content1 content2Bytes := r.Content2 content3Bytes := r.Content3 blockBytes := bytes.Join([][]byte{ Encode24BitLength(headerBytes), headerBytes, Encode24BitLength(content1Bytes), content1Bytes, Encode24BitLength(content2Bytes), content2Bytes, Encode24BitLength(content3Bytes), content3Bytes, }, []byte{}) return bytes.Join([][]byte{Encode24BitLength(blockBytes), blockBytes}, []byte{}) } func (r *SignerRequest) String() string { return fmt.Sprintf( "v:%d %s s:%d r:%d p:%d md:%d days:%d spkac:%d '%s' '%s' '%s'", r.Version, r.Action, r.System, r.Root, r.Profile, r.MdAlgorithm, r.Days, r.Spkac, r.Content1, r.Content2, r.Content3, ) } func NewNulRequest() *SignerRequest { return &SignerRequest{ Version: shared.ProtocolVersion, Action: shared.ActionNul, Content1: []byte(time.Now().UTC().Format(signerTimeFormat)), } }