FAQ
Also, can you change the description to be more explicit? Say how you
fixed what issue.
On Tue, Oct 22, 2013 at 2:36 PM, wrote:
Reviewers: agl1, dfc,

Message:
Hello agl@golang.org, dave@cheney.net (cc: golang-dev@googlegroups.com,
hanwen@google.com, jpsugar@google.com),

I'd like you to review this change to
https://code.google.com/p/go.crypto


Description:
go.crypto/ssh: Implement CertTime to fix an issue with some time
conversions.

Please review this at https://codereview.appspot.com/15520047/

Affected files (+36, -9 lines):
M ssh/certs.go
M ssh/keys_test.go


Index: ssh/certs.go
===================================================================
--- a/ssh/certs.go
+++ b/ssh/certs.go
@@ -35,6 +35,34 @@
Data string
}

+// A time.Time cannot represent seconds higher than 1<<63 - 1. However,
+// conversion from uint64 to int64 for values higher than this will result
in
+// negative int64 values and result in times before unix epoch that are not
+// intended to be used with certs. maxInt64 in unix seconds would be
+// 292277026596-12-04 15:30:07 +0000 UTC. We are safe until the year
+// 292,277,026,596 in setting this value to maxInt64 for values above
+// maxInt64. A use case for this is the "forever" setting where ValidAfter
is 0
+// (all bytes 0x00) and ValidBefore is 1<<64 - 1 (all bytes 0xFF). OpenSSH
does
+// something similar to this by clamping to INT_MAX.
+
+// CertTime represents an unsigned 64bit time value in seconds starting
from
+// unix epoch. We use CertTime instead of time.Time in order to properly
+// handle time values above what a time.Time can represent and prevent
values
+// before unix epoch.
+type CertTime uint64
+
+func (ct CertTime) Time() time.Time {
+ const maxInt64 = 1<<63 - 1
+ if ct > maxInt64 {
+ return time.Unix(maxInt64, 0)
+ }
+ return time.Unix(int64(ct), 0)
+}
+
+func (ct CertTime) IsTheEnd() bool {
+ return ct == 1<<64-1
+}
+
// An OpenSSHCertV01 represents an OpenSSH certificate as defined in
// [PROTOCOL.certkeys]?rev=1.8.
type OpenSSHCertV01 struct {
@@ -44,7 +72,7 @@
Type uint32
KeyId string
ValidPrincipals []string
- ValidAfter, ValidBefore time.Time
+ ValidAfter, ValidBefore CertTime
CriticalOptions []tuple
Extensions []tuple
Reserved []byte
@@ -115,8 +143,8 @@
r = marshalUint32(r, cert.Type)
r = marshalString(r, []byte(cert.KeyId))
r = marshalLengthPrefixedNameList(r, cert.ValidPrincipals)
- r = marshalUint64(r, uint64(cert.ValidAfter.Unix()))
- r = marshalUint64(r, uint64(cert.ValidBefore.Unix()))
+ r = marshalUint64(r, uint64(cert.ValidAfter))
+ r = marshalUint64(r, uint64(cert.ValidBefore))
r = marshalTupleList(r, cert.CriticalOptions)
r = marshalTupleList(r, cert.Extensions)
r = marshalString(r, cert.Reserved)
@@ -195,13 +223,13 @@
if !ok {
return
}
- cert.ValidAfter = time.Unix(int64(va), 0)
+ cert.ValidAfter = CertTime(va)

vb, in, ok := parseUint64(in)
if !ok {
return
}
- cert.ValidBefore = time.Unix(int64(vb), 0)
+ cert.ValidBefore = CertTime(vb)

if cert.CriticalOptions, in, ok = parseTupleList(in); !ok {
return
Index: ssh/keys_test.go
===================================================================
--- a/ssh/keys_test.go
+++ b/ssh/keys_test.go
@@ -9,7 +9,6 @@
"reflect"
"strings"
"testing"
- "time"
)

var (
@@ -46,9 +45,9 @@
Nonce: []byte{}, // To pass reflect.DeepEqual
after marshal & parse, this must be non-nil
Key: ecdsaKey.PublicKey(),
ValidPrincipals: []string{"gopher1", "gopher2"}, //
increases test coverage
- ValidAfter: time.Now().Truncate(time.Second),
- ValidBefore:
time.Now().Truncate(time.Second).Add(time.Hour),
- Reserved: []byte{}, // To pass reflect.DeepEqual
after marshal & parse, this must be non-nil
+ ValidAfter: 0, // unix
epoch
+ ValidBefore: 0xFFFFFFFFFFFFFFFF, // The end
of currently representable time.
+ Reserved: []byte{}, // To pass
reflect.DeepEqual after marshal & parse, this must be non-nil
SignatureKey: rsaKey.PublicKey(),
}
sigBytes, _ := rsaKey.Sign(rand.Reader, testCert.BytesForSigning())


--
Han-Wen Nienhuys
Google Munich
hanwen@google.com

--

---
You received this message because you are subscribed to the Google Groups "golang-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-dev+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Search Discussions

Discussion Posts

Previous

Follow ups

Related Discussions

Discussion Navigation
viewthread | post
posts ‹ prev | 7 of 11 | next ›
Discussion Overview
groupgolang-dev @
categoriesgo
postedOct 22, '13 at 9:36p
activeOct 23, '13 at 4:44p
posts11
users4
websitegolang.org

People

Translate

site design / logo © 2021 Grokbase