Skip to content

Commit

Permalink
Merge pull request #54 from smallstep/permanent-identifier
Browse files Browse the repository at this point in the history
Permanent identifier
  • Loading branch information
maraino authored Aug 11, 2022
2 parents 72ddf42 + 022ae3d commit ab04eab
Show file tree
Hide file tree
Showing 19 changed files with 512 additions and 163 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-20.04
strategy:
matrix:
go: [ '1.17', '1.18' ]
go: [ '1.18', '1.19' ]
steps:
- name: Install dependencies
run: sudo apt update && sudo apt install -y libpcsclite-dev
Expand All @@ -25,7 +25,7 @@ jobs:
- name: golangci-lint
uses: golangci/golangci-lint-action@v2
with:
version: 'v1.46.2'
version: 'v1.48'
args: --timeout=30m
- name: Test
run: V=1 make ci
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-20.04
strategy:
matrix:
go: [ '1.17', '1.18' ]
go: [ '1.18', '1.19' ]
steps:
- name: Install dependencies
run: sudo apt update && sudo apt install -y libpcsclite-dev
Expand All @@ -27,13 +27,13 @@ jobs:
- name: golangci-lint
uses: golangci/golangci-lint-action@v2
with:
version: 'v1.46.2'
version: 'v1.48'
args: --timeout=30m
- name: Test
run: V=1 make ci
- name: Codecov
uses: codecov/[email protected]
if: matrix.go == '1.18'
if: matrix.go == '1.19'
with:
file: ./coverage.out
name: codecov-umbrella
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module go.step.sm/crypto

go 1.17
go 1.18

require (
cloud.google.com/go/kms v1.4.0
Expand Down
4 changes: 0 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,6 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
Expand Down Expand Up @@ -399,7 +398,6 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
Expand Down Expand Up @@ -488,7 +486,6 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211031064116-611d5d643895/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
Expand Down Expand Up @@ -572,7 +569,6 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
Expand Down
1 change: 1 addition & 0 deletions internal/bcrypt_pbkdf/bcrypt_pbkdf.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

// Package bcrypt_pbkdf implements password-based key derivation function based
// on bcrypt compatible with bcrypt_pbkdf(3) from OpenBSD.
//
//nolint:revive // ignore underscore in package
package bcrypt_pbkdf

Expand Down
1 change: 1 addition & 0 deletions internal/bcrypt_pbkdf/bcrypt_pbkdf_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright 2014 Dmitry Chestnykh. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//
//nolint:revive // ignore underscore in package
package bcrypt_pbkdf

Expand Down
3 changes: 1 addition & 2 deletions internal/utils/io_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package utils

import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"reflect"
Expand Down Expand Up @@ -67,7 +66,7 @@ func TestReadPasswordFromFile(t *testing.T) {
}

func TestWriteFile(t *testing.T) {
tmpDir, err := ioutil.TempDir(os.TempDir(), "go-tests")
tmpDir, err := os.MkdirTemp(os.TempDir(), "go-tests")
if err != nil {
t.Fatal(err)
}
Expand Down
5 changes: 2 additions & 3 deletions jose/generate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"crypto/x509"
"encoding/json"
"encoding/pem"
"io/ioutil"
"math/big"
"os"
"reflect"
Expand Down Expand Up @@ -357,8 +356,8 @@ func newCert(t *testing.T, keyUsage x509.KeyUsage) []byte {
return cert
}

func tempFile(t *testing.T) (_ *os.File, cleanup func()) {
f, err := ioutil.TempFile("" /* use default tmp dir */, "jose-generate-test")
func tempFile(t *testing.T) (*os.File, func()) {
f, err := os.CreateTemp("", "jose-generate-test")
assert.NoError(t, err)
return f, func() {
f.Close()
Expand Down
2 changes: 2 additions & 0 deletions jose/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ var ErrInvalidID = jwt.ErrInvalidID
var ErrIssuedInTheFuture = jwt.ErrIssuedInTheFuture

// Key management algorithms
//
//nolint:revive // use standard names in upper-case
const (
RSA1_5 = KeyAlgorithm("RSA1_5") // RSA-PKCS1v1.5
Expand Down Expand Up @@ -162,6 +163,7 @@ const (
)

// Content encryption algorithms
//
//nolint:revive // use standard names in upper-case
const (
A128CBC_HS256 = ContentEncryption("A128CBC-HS256") // AES-CBC + HMAC-SHA256 (128)
Expand Down
2 changes: 1 addition & 1 deletion sshutil/certificate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ func TestNewCertificate(t *testing.T) {
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("NewCertificate() = \n%+v, want \n%+v", got, tt.want)
t.Errorf("NewCertificate() = %v, want %v", got, tt.want)
}
})
}
Expand Down
1 change: 1 addition & 0 deletions tlsutil/renewer.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ type RenewFunc func() (*tls.Certificate, *tls.Config, error)
var MinCertDuration = time.Minute

// Renewer automatically renews a tls certificate using a RenewFunc.
//
//nolint:gocritic // ignore exposedSyncMutex
type Renewer struct {
sync.RWMutex
Expand Down
64 changes: 32 additions & 32 deletions x25519/x25519.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,13 +110,13 @@ func (p PrivateKey) Sign(rand io.Reader, message []byte, opts crypto.SignerOpts)
// It implements the XEdDSA sign method defined in
// https://signal.org/docs/specifications/xeddsa/#xeddsa
//
// xeddsa_sign(k, M, Z):
// A, a = calculate_key_pair(k)
// r = hash1(a || M || Z) (mod q)
// R = rB
// h = hash(R || A || M) (mod q)
// s = r + ha (mod q)
// return R || s
// xeddsa_sign(k, M, Z):
// A, a = calculate_key_pair(k)
// r = hash1(a || M || Z) (mod q)
// R = rB
// h = hash(R || A || M) (mod q)
// s = r + ha (mod q)
// return R || s
func Sign(rand io.Reader, p PrivateKey, message []byte) (signature []byte, err error) {
if l := len(p); l != PrivateKeySize {
panic("x25519: bad private key length: " + strconv.Itoa(l))
Expand Down Expand Up @@ -184,17 +184,17 @@ func Sign(rand io.Reader, p PrivateKey, message []byte) (signature []byte, err e
// It implements the XEdDSA verify method defined in
// https://signal.org/docs/specifications/xeddsa/#xeddsa
//
// xeddsa_verify(u, M, (R || s)):
// if u >= p or R.y >= 2|p| or s >= 2|q|:
// return false
// A = convert_mont(u)
// if not on_curve(A):
// return false
// h = hash(R || A || M) (mod q)
// Rcheck = sB - hA
// if bytes_equal(R, Rcheck):
// return true
// return false
// xeddsa_verify(u, M, (R || s)):
// if u >= p or R.y >= 2|p| or s >= 2|q|:
// return false
// A = convert_mont(u)
// if not on_curve(A):
// return false
// h = hash(R || A || M) (mod q)
// Rcheck = sB - hA
// if bytes_equal(R, Rcheck):
// return true
// return false
func Verify(publicKey PublicKey, message, sig []byte) bool {
// The following code should be equivalent to:
//
Expand Down Expand Up @@ -242,15 +242,15 @@ func Verify(publicKey PublicKey, message, sig []byte) bool {
// public key and private key (A, a) as defined in
// https://signal.org/docs/specifications/xeddsa/#elliptic-curve-conversions
//
// calculate_key_pair(k):
// E = kB
// A.y = E.y
// A.s = 0
// if E.s == 1:
// a = -k (mod q)
// else:
// a = k (mod q)
// return A, a
// calculate_key_pair(k):
// E = kB
// A.y = E.y
// A.s = 0
// if E.s == 1:
// a = -k (mod q)
// else:
// a = k (mod q)
// return A, a
func (p PrivateKey) calculateKeyPair() ([]byte, *edwards25519.Scalar, error) {
var pA edwards25519.Point
var sa edwards25519.Scalar
Expand Down Expand Up @@ -278,11 +278,11 @@ func (p PrivateKey) calculateKeyPair() ([]byte, *edwards25519.Scalar, error) {
// point P, according to
// https://signal.org/docs/specifications/xeddsa/#elliptic-curve-conversions
//
// convert_mont(u):
// umasked = u (mod 2|p|)
// P.y = u_to_y(umasked)
// P.s = 0
// return P
// convert_mont(u):
// umasked = u (mod 2|p|)
// P.y = u_to_y(umasked)
// P.s = 0
// return P
func convertMont(u PublicKey) (*edwards25519.Point, error) {
um, err := (&field.Element{}).SetBytes(u)
if err != nil {
Expand Down
24 changes: 15 additions & 9 deletions x509util/certificate.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,18 @@ func NewCertificate(cr *x509.CertificateRequest, opts ...Option) (*Certificate,
cert.PublicKey = cr.PublicKey
cert.PublicKeyAlgorithm = cr.PublicKeyAlgorithm

// Generate the subjectAltName extension if the certificate contains SANs
// that are not supported in the Go standard library.
if cert.hasExtendedSANs() && !cert.hasExtension(oidExtensionSubjectAltName) {
ext, err := createSubjectAltNameExtension(&cert, cert.Subject.IsEmpty())
if err != nil {
return nil, err
}
// Prepend extension to achieve a certificate as similar as possible to
// the one generated by the Go standard library.
cert.Extensions = append([]Extension{ext}, cert.Extensions...)
}

return &cert, nil
}

Expand All @@ -83,15 +95,9 @@ func (c *Certificate) GetCertificate() *x509.Certificate {
// Subject
c.Subject.Set(cert)

if c.hasExtendedSANs() && !c.hasExtension(oidExtensionSubjectAltName) {
subjectAltNameExtension, err := createSubjectAltNameExtension(c, subjectIsEmpty(cert.Subject))
if err != nil {
panic(err)
}
subjectAltNameExtension.Set(cert)
} else {
// When we have no extended SANs, use the golang x509 lib to create the
// extension instead
// When we have no extended SANs, use the golang x509 lib to create the
// extension instead
if !c.hasExtension(oidExtensionSubjectAltName) {
cert.DNSNames = c.DNSNames
cert.EmailAddresses = c.EmailAddresses
cert.IPAddresses = c.IPAddresses
Expand Down
32 changes: 31 additions & 1 deletion x509util/certificate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,16 @@ func TestNewCertificate(t *testing.T) {
crBadSignateure, _ := createCertificateRequest(t, "fail", []string{"foo.com"})
crBadSignateure.PublicKey = priv.Public()

customSANsData := CreateTemplateData("commonName", nil)
customSANsData.Set(SANsKey, []SubjectAlternativeName{
{Type: PermanentIdentifierType, Value: "123456"},
{Type: "1.2.3.4", Value: "utf8:otherName"},
})
badCustomSANsData := CreateTemplateData("commonName", nil)
badCustomSANsData.Set(SANsKey, []SubjectAlternativeName{
{Type: "1.2.3.4", Value: "int:not-an-int"},
})

ipNet := func(s string) *net.IPNet {
_, ipNet, err := net.ParseCIDR(s)
if err != nil {
Expand Down Expand Up @@ -153,6 +163,25 @@ func TestNewCertificate(t *testing.T) {
PublicKey: priv.Public(),
PublicKeyAlgorithm: x509.Ed25519,
}, false},
{"okCustomSANs", args{cr, []Option{WithTemplate(DefaultLeafTemplate, customSANsData)}}, &Certificate{
Subject: Subject{CommonName: "commonName"},
SANs: []SubjectAlternativeName{
{Type: PermanentIdentifierType, Value: "123456"},
{Type: "1.2.3.4", Value: "utf8:otherName"},
},
Extensions: []Extension{{
ID: ObjectIdentifier{2, 5, 29, 17},
Critical: false,
Value: []byte{48, 44, 160, 22, 6, 8, 43, 6, 1, 5, 5, 7, 8, 3, 160, 10, 48, 8, 12, 6, 49, 50, 51, 52, 53, 54, 160, 18, 6, 3, 42, 3, 4, 160, 11, 12, 9, 111, 116, 104, 101, 114, 78, 97, 109, 101},
}},
KeyUsage: KeyUsage(x509.KeyUsageDigitalSignature),
ExtKeyUsage: ExtKeyUsage([]x509.ExtKeyUsage{
x509.ExtKeyUsageServerAuth,
x509.ExtKeyUsageClientAuth,
}),
PublicKey: priv.Public(),
PublicKeyAlgorithm: x509.Ed25519,
}, false},
{"okExample", args{cr, []Option{WithTemplateFile("./testdata/example.tpl", TemplateData{
SANsKey: []SubjectAlternativeName{
{Type: "dns", Value: "foo.com"},
Expand Down Expand Up @@ -241,6 +270,7 @@ func TestNewCertificate(t *testing.T) {
{"failTemplate", args{cr, []Option{WithTemplate(`{{ fail "fatal error }}`, CreateTemplateData("commonName", []string{"foo.com"}))}}, nil, true},
{"missingTemplate", args{cr, []Option{WithTemplateFile("./testdata/missing.tpl", CreateTemplateData("commonName", []string{"foo.com"}))}}, nil, true},
{"badJson", args{cr, []Option{WithTemplate(`"this is not a json object"`, CreateTemplateData("commonName", []string{"foo.com"}))}}, nil, true},
{"failCustomSANs", args{cr, []Option{WithTemplate(DefaultLeafTemplate, badCustomSANsData)}}, nil, true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down Expand Up @@ -382,7 +412,7 @@ func TestCertificate_GetCertificate(t *testing.T) {
PublicKey: tt.fields.PublicKey,
}
if got := c.GetCertificate(); !reflect.DeepEqual(got, tt.want) {
t.Errorf("Certificate.GetCertificate() = \n%+v, want \n%+v", got, tt.want)
t.Errorf("Certificate.GetCertificate() = %v, want %v", got, tt.want)
}
})
}
Expand Down
Loading

0 comments on commit ab04eab

Please sign in to comment.