cacert-gosigner/datastructures/signerrequest.go

113 lines
3 KiB
Go

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,
shorten(r.Content1),
shorten(r.Content2),
shorten(r.Content3),
)
}
func shorten(original []byte) []byte {
if len(original) > 20 {
return original[:20]
}
return original
}
func NewNulRequest() *SignerRequest {
return &SignerRequest{
Version: shared.ProtocolVersion,
Action: shared.ActionNul,
Content1: []byte(time.Now().UTC().Format(signerTimeFormat)),
}
}