Skip to content
17 changes: 12 additions & 5 deletions std/engine/basic/engine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,9 @@ func TestRoute(t *testing.T) {
hitCnt := 0
spec := engine.Spec()

// Fixed SigTime for deterministic test vectors: 2024-01-01 00:00:00 UTC
fixedSigTime := optional.Some(time.Duration(1704067200000) * time.Millisecond)

handler := func(args ndn.InterestHandlerArgs) {
hitCnt += 1
require.Equal(t, []byte(
Expand All @@ -278,6 +281,7 @@ func TestRoute(t *testing.T) {
args.Interest.Name(),
&ndn.DataConfig{
ContentType: optional.Some(ndn.ContentTypeBlob),
SigTime: fixedSigTime,
},
enc.Wire{[]byte("test")},
sig.NewTestSigner(enc.Name{}, 0))
Expand All @@ -291,8 +295,8 @@ func TestRoute(t *testing.T) {
require.Equal(t, 1, hitCnt)
buf := tu.NoErr(face.Consume())
require.Equal(t, enc.Buffer(
"\x06\x22\x07\x10\x08\x03not\x08\timportant\x14\x03\x18\x01\x00\x15\x04test"+
"\x16\x03\x1b\x01\xc8",
"\x06\x2c\x07\x10\x08\x03not\x08\timportant\x14\x03\x18\x01\x00\x15\x04test"+
"\x16\x0d\x1b\x01\xc8(\x08\x00\x00\x01\x8c\xc2Q\xf4\x00",
), buf)
})
}
Expand All @@ -302,13 +306,16 @@ func TestPitToken(t *testing.T) {
executeTest(t, func(face *face.DummyFace, engine *basic_engine.Engine, timer *basic_engine.DummyTimer) {
hitCnt := 0
spec := engine.Spec()
// Fixed SigTime for deterministic test vectors: 2024-01-01 00:00:00 UTC
fixedSigTime := optional.Some(time.Duration(1704067200000) * time.Millisecond)

handler := func(args ndn.InterestHandlerArgs) {
hitCnt += 1
data, err := spec.MakeData(
args.Interest.Name(),
&ndn.DataConfig{
ContentType: optional.Some(ndn.ContentTypeBlob),
SigTime: fixedSigTime,
},
enc.Wire{[]byte("test")},
sig.NewTestSigner(enc.Name{}, 0))
Expand All @@ -324,9 +331,9 @@ func TestPitToken(t *testing.T) {
))
buf := tu.NoErr(face.Consume())
require.Equal(t, enc.Buffer(
"\x64\x2c\x62\x04\x01\x02\x03\x04\x50\x24"+
"\x06\x22\x07\x10\x08\x03not\x08\timportant\x14\x03\x18\x01\x00\x15\x04test"+
"\x16\x03\x1b\x01\xc8",
"\x64\x36\x62\x04\x01\x02\x03\x04\x50\x2e"+
"\x06\x2c\x07\x10\x08\x03not\x08\timportant\x14\x03\x18\x01\x00\x15\x04test"+
"\x16\x0d\x1b\x01\xc8(\x08\x00\x00\x01\x8c\xc2Q\xf4\x00",
), buf)
})
}
3 changes: 3 additions & 0 deletions std/ndn/spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ type DataConfig struct {
SigNotBefore optional.Optional[time.Time]
SigNotAfter optional.Optional[time.Time]

// Signature time, used to determine time the packet was signed
SigTime optional.Optional[time.Duration]

// Cross Schema attachment
CrossSchema enc.Wire
}
Expand Down
14 changes: 12 additions & 2 deletions std/ndn/spec_2022/spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,13 @@ func (d *Data) SigNonce() []byte {
return nil
}

// (AI GENERATED DESCRIPTION): Returns the signature timestamp of the Data packet (currently unimplemented and returns nil).
// (AI GENERATED DESCRIPTION): Returns the signature timestamp of the Data packet if present, else returns nil.
func (d *Data) SigTime() *time.Time {
return nil
if d.SignatureInfo != nil && d.SignatureInfo.SignatureTime.IsSet() {
return utils.IdPtr(time.UnixMilli(d.SignatureInfo.SignatureTime.Unwrap().Milliseconds()))
} else {
return nil
}
}

// (AI GENERATED DESCRIPTION): Sets the Data packet’s SignatureInfo.SignatureTime to the given time (converted to a millisecond duration) or clears the field if the argument is nil.
Expand Down Expand Up @@ -262,6 +266,11 @@ func (Spec) MakeData(name enc.Name, config *ndn.DataConfig, content enc.Wire, si
if config == nil {
return nil, ndn.ErrInvalidValue{Item: "Data.DataConfig", Value: nil}
}

Comment thread
vchinn04 marked this conversation as resolved.
if !config.SigTime.IsSet() {
config.SigTime = optional.Some(time.Duration(time.Now().UnixMilli()) * time.Millisecond)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I think this should be set by the signer (and Interest should do the same). Otherwise, it would hard to do integration test by injection.
This is also the reason why we have Timer interface:

ndnd/std/ndn/engine.go

Lines 59 to 69 in e716745

type Timer interface {
// Now returns current time.
Now() time.Time
// Sleep sleeps for the duration.
Sleep(time.Duration)
// Schedule schedules the callback function to be called after the duration,
// and returns a cancel callback to cancel the scheduled function.
Schedule(time.Duration, func()) func() error
// Nonce generates a random nonce.
Nonce() []byte
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case should we just remove default packet signature time setting?

}

finalBlock := []byte(nil)
if fbid, ok := config.FinalBlockID.Get(); ok {
finalBlock = fbid.Bytes()
Expand Down Expand Up @@ -289,6 +298,7 @@ func (Spec) MakeData(name enc.Name, config *ndn.DataConfig, content enc.Wire, si

data.SignatureInfo = &SignatureInfo{
SignatureType: uint64(signer.Type()),
SignatureTime: config.SigTime,
}

if key := signer.KeyLocator(); key != nil {
Expand Down
44 changes: 27 additions & 17 deletions std/ndn/spec_2022/spec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,40 +21,42 @@ func TestMakeDataBasic(t *testing.T) {
tu.SetT(t)

spec := spec_2022.Spec{}
// Fixed SigTime for deterministic test vectors: 2024-01-01 00:00:00 UTC
fixedSigTime := optional.Some(time.Duration(1704067200000) * time.Millisecond)

data, err := spec.MakeData(
tu.NoErr(enc.NameFromStr("/local/ndn/prefix")),
&ndn.DataConfig{
ContentType: optional.Some(ndn.ContentTypeBlob),
SigTime: fixedSigTime,
},
nil,
sig.NewSha256Signer(),
)
require.NoError(t, err)
require.Equal(t, []byte(
"\x06\x42\x07\x14\x08\x05local\x08\x03ndn\x08\x06prefix"+
"\x06L\x07\x14\x08\x05local\x08\x03ndn\x08\x06prefix"+
"\x14\x03\x18\x01\x00"+
"\x16\x03\x1b\x01\x00"+
"\x17 \x7f1\xe4\t\xc5z/\x1d\r\xdaVh8\xfd\xd9\x94"+
"\xd8'S\x13[\xd7\x15\xa5\x9d%^\x80\xf2\xab\xf0\xb5"),
"\x16\x0d\x1b\x01\x00(\x08\x00\x00\x01\x8c\xc2Q\xf4\x00"+
"\x17 *\x17?\xd6i\xdcB\xd0\xf6G\x1d\x0b\xb6\x93\xd4{\xddw\xc6$\x04\x00\x0eN\xb7\x07\x5c\x80K+O\x86"),
data.Wire.Join())

data, err = spec.MakeData(
tu.NoErr(enc.NameFromStr("/local/ndn/prefix")),
&ndn.DataConfig{
ContentType: optional.Some(ndn.ContentTypeBlob),
SigTime: fixedSigTime,
},
enc.Wire{[]byte("01020304")},
sig.NewSha256Signer(),
)
require.NoError(t, err)
require.Equal(t, []byte(
"\x06L\x07\x14\x08\x05local\x08\x03ndn\x08\x06prefix"+
"\x06V\x07\x14\x08\x05local\x08\x03ndn\x08\x06prefix"+
"\x14\x03\x18\x01\x00"+
"\x15\x0801020304"+
"\x16\x03\x1b\x01\x00"+
"\x17 \x94\xe9\xda\x91\x1a\x11\xfft\x02i:G\x0cO\xdd!"+
"\xe0\xc7\xb6\xfd\x8f\x9cn\xc5\x93{\x93\x04\xe0\xdf\xa6S"),
"\x16\x0d\x1b\x01\x00(\x08\x00\x00\x01\x8c\xc2Q\xf4\x00"+
"\x17 \xaf\x02\x9d\xf3\x9a\x05s\x83\xefv\x05\xef\x81=\xdb.\xc72$v\x13\xb3\xae\x80\x83+\xe8W\xfeP\x1f}"),
data.Wire.Join())

data, err = spec.MakeData(
Expand All @@ -75,39 +77,43 @@ func TestMakeDataBasic(t *testing.T) {
tu.NoErr(enc.NameFromStr("/E")),
&ndn.DataConfig{
ContentType: optional.None[ndn.ContentType](),
SigTime: fixedSigTime,
},
enc.Wire{},
sig.NewSha256Signer(),
)
require.NoError(t, err)
require.Equal(t, tu.NoErr(hex.DecodeString(
"06300703080145"+
"1400150016031b0100"+
"1720f965ee682c6973c3cbaa7b69e4c7063680f83be93a46be2ccc98686134354b66")),
"063a070308014514001500"+
"160d1b010028080000018cc251f400"+
"1720f7b2d57151cb8d6fe2c616adee9195c9d00f3c422754709f750375bae2e91e30")),
data.Wire.Join())
}

// (AI GENERATED DESCRIPTION): Creates a signed Data packet with the specified name, optional meta‑information (content type, freshness period, final block ID), optional content, and the provided signer.
func TestMakeDataMetaInfo(t *testing.T) {
tu.SetT(t)
spec := spec_2022.Spec{}
// Fixed SigTime for deterministic test vectors: 2024-01-01 00:00:00 UTC
fixedSigTime := optional.Some(time.Duration(1704067200000) * time.Millisecond)

data, err := spec.MakeData(
tu.NoErr(enc.NameFromStr("/local/ndn/prefix/37=%00")),
&ndn.DataConfig{
ContentType: optional.Some(ndn.ContentTypeBlob),
Freshness: optional.Some(1000 * time.Millisecond),
FinalBlockID: optional.Some(enc.NewSequenceNumComponent(2)),
SigTime: fixedSigTime,
},
nil,
sig.NewSha256Signer(),
)
require.NoError(t, err)
require.Equal(t, []byte(
"\x06\x4e\x07\x17\x08\x05local\x08\x03ndn\x08\x06prefix\x25\x01\x00"+
"\x14\x0c\x18\x01\x00\x19\x02\x03\xe8\x1a\x03\x3a\x01\x02"+
"\x16\x03\x1b\x01\x00"+
"\x17 \x0f^\xa1\x0c\xa7\xf5Fb\xf0\x9cOT\xe0FeC\x8f92\x04\x9d\xabP\x80o'\x94\xaa={hQ"),
"\x06X\x07\x17\x08\x05local\x08\x03ndn\x08\x06prefix\x25\x01\x00"+
"\x14\x0c\x18\x01\x00\x19\x02\x03\xe8\x1a\x03:\x01\x02"+
"\x16\x0d\x1b\x01\x00(\x08\x00\x00\x01\x8c\xc2Q\xf4\x00"+
"\x17 \xa9v\x8a(\xb3^\xf8\x1c\xce*\xa8\xf2\x14\x81\x8cQ\xcc\xb8I\xc6\xd6\xa7\x99z\x88JKu\x81\xc4[N"),
data.Wire.Join())
}

Expand Down Expand Up @@ -148,19 +154,23 @@ func (testSigner) Public() ([]byte, error) {
func TestMakeDataShrink(t *testing.T) {
tu.SetT(t)
spec := spec_2022.Spec{}
// Fixed SigTime for deterministic test vectors: 2024-01-01 00:00:00 UTC
fixedSigTime := optional.Some(time.Duration(1704067200000) * time.Millisecond)

data, err := spec.MakeData(
tu.NoErr(enc.NameFromStr("/test")),
&ndn.DataConfig{
ContentType: optional.Some(ndn.ContentTypeBlob),
SigTime: fixedSigTime,
},
nil,
testSigner{},
)
require.NoError(t, err)
require.Equal(t, []byte{
0x6, 0x22, 0x7, 0x6, 0x8, 0x4, 0x74, 0x65, 0x73, 0x74, 0x14, 0x3, 0x18, 0x1, 0x0,
0x16, 0xc, 0x1b, 0x1, 0xc8, 0x1c, 0x7, 0x7, 0x5, 0x8, 0x3, 0x4b, 0x45, 0x59,
0x6, 0x2c, 0x7, 0x6, 0x8, 0x4, 0x74, 0x65, 0x73, 0x74, 0x14, 0x3, 0x18, 0x1, 0x0,
0x16, 0x16, 0x1b, 0x1, 0xc8, 0x1c, 0x7, 0x7, 0x5, 0x8, 0x3, 0x4b, 0x45, 0x59,
0x28, 0x8, 0x0, 0x0, 0x1, 0x8c, 0xc2, 0x51, 0xf4, 0x0,
0x17, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0},
data.Wire.Join())
}
Expand Down
13 changes: 13 additions & 0 deletions std/security/certificate.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ func SignCert(args SignCertArgs) (enc.Wire, error) {
Freshness: optional.Some(time.Hour),
SigNotBefore: optional.Some(args.NotBefore),
SigNotAfter: optional.Some(args.NotAfter),
SigTime: optional.Some(time.Duration(time.Now().UnixMilli()) * time.Millisecond),
CrossSchema: args.CrossSchema,
}
signer := sig.AsContextSigner(args.Signer)
Expand Down Expand Up @@ -199,3 +200,15 @@ func DecodeCertList(content enc.Wire) ([]enc.Name, error) {
}
return names, nil
}

// AppendCertList appends a certificate name list to a certificate list by creating a new certificate list
func AppendCertList(content enc.Wire, names []enc.Name) (enc.Wire, error) {
certList, err := DecodeCertList(content)
if err != nil {
return nil, err
}

newList := append(certList, names...)

return EncodeCertList(newList)
}
19 changes: 19 additions & 0 deletions std/security/certificate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,3 +191,22 @@ func TestEncodeDecodeCertList(t *testing.T) {
_, err = sec.DecodeCertList(enc.Wire{[]byte{0x01, 0x02}})
require.Error(t, err)
}

func TestAppendCertList(t *testing.T) {
tu.SetT(t)
n1 := tu.NoErr(enc.NameFromStr("/ndn/alice/KEY/aa/self/v=1"))
n2 := tu.NoErr(enc.NameFromStr("/ndn/alice/KEY/bb/ndn/v=2"))

wire, err := sec.EncodeCertList([]enc.Name{n1})
require.NoError(t, err)
decoded, err := sec.DecodeCertList(wire)
require.NoError(t, err)
require.Equal(t, []enc.Name{n1}, decoded)

wire2, err2 := sec.AppendCertList(wire, []enc.Name{n2})
require.NoError(t, err2)

decoded, err = sec.DecodeCertList(wire2)
require.NoError(t, err)
require.Equal(t, []enc.Name{n1, n2}, decoded)
}
Loading
Loading