Skip to content

Commit

Permalink
update go.mod
Browse files Browse the repository at this point in the history
  • Loading branch information
RyuaNerin committed Jan 17, 2024
1 parent 0662b86 commit 07200b9
Show file tree
Hide file tree
Showing 6 changed files with 543 additions and 3 deletions.
80 changes: 80 additions & 0 deletions eckcdsa/eckcdsa_asn1.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package eckcdsa

import (
"errors"
"hash"
"io"
"math/big"

"golang.org/x/crypto/cryptobyte"

Check failure on line 9 in eckcdsa/eckcdsa_asn1.go

View workflow job for this annotation

GitHub Actions / macos_arm64 (1.17)

no required module provides package golang.org/x/crypto/cryptobyte; to add it:

Check failure on line 9 in eckcdsa/eckcdsa_asn1.go

View workflow job for this annotation

GitHub Actions / macos_arm64 (1.18)

no required module provides package golang.org/x/crypto/cryptobyte; to add it:

Check failure on line 9 in eckcdsa/eckcdsa_asn1.go

View workflow job for this annotation

GitHub Actions / ubuntu_amd64 (1.20)

no required module provides package golang.org/x/crypto/cryptobyte; to add it:

Check failure on line 9 in eckcdsa/eckcdsa_asn1.go

View workflow job for this annotation

GitHub Actions / ubuntu_amd64 (1.21)

no required module provides package golang.org/x/crypto/cryptobyte; to add it:
"golang.org/x/crypto/cryptobyte/asn1"

Check failure on line 10 in eckcdsa/eckcdsa_asn1.go

View workflow job for this annotation

GitHub Actions / macos_arm64 (1.17)

no required module provides package golang.org/x/crypto/cryptobyte/asn1; to add it:

Check failure on line 10 in eckcdsa/eckcdsa_asn1.go

View workflow job for this annotation

GitHub Actions / macos_arm64 (1.18)

no required module provides package golang.org/x/crypto/cryptobyte/asn1; to add it:

Check failure on line 10 in eckcdsa/eckcdsa_asn1.go

View workflow job for this annotation

GitHub Actions / ubuntu_amd64 (1.20)

no required module provides package golang.org/x/crypto/cryptobyte/asn1; to add it:

Check failure on line 10 in eckcdsa/eckcdsa_asn1.go

View workflow job for this annotation

GitHub Actions / ubuntu_amd64 (1.21)

no required module provides package golang.org/x/crypto/cryptobyte/asn1; to add it:
)

// Sign data using K generated randomly like in crypto/ecdsa packages.
// SianASN1 returns the ASN.1 encoded signature.
func SignASN1(randReader io.Reader, priv *PrivateKey, h hash.Hash, M []byte) (sig []byte, err error) {
r, s, err := Sign(randReader, priv, h, M)
if err != nil {
return nil, err
}

return encodeSignature(r.Bytes(), s.Bytes())
}

// VerifyASN1 verifies the ASN.1 encoded signature, sig, M, of hash using the
// public key, pub. Its return value records whether the signature is valid.
func VerifyASN1(pub *PublicKey, h hash.Hash, M, sig []byte) bool {
r, s, err := parseSignature(sig)
if err != nil {
return false
}

return Verify(
pub,
h,
M,
new(big.Int).SetBytes(r),
new(big.Int).SetBytes(s),
)
}

// https://github.com/golang/go/blob/go1.21.6/src/crypto/ecdsa/ecdsa.go#L338-L345
func encodeSignature(r, s []byte) ([]byte, error) {
var b cryptobyte.Builder
b.AddASN1(asn1.SEQUENCE, func(b *cryptobyte.Builder) {
addASN1IntBytes(b, r)
addASN1IntBytes(b, s)
})
return b.Bytes()
}

// https://github.com/golang/go/blob/go1.21.6/src/crypto/ecdsa/ecdsa.go#L349-L363
func addASN1IntBytes(b *cryptobyte.Builder, bytes []byte) {
for len(bytes) > 0 && bytes[0] == 0 {
bytes = bytes[1:]
}
if len(bytes) == 0 {
b.SetError(errors.New("invalid integer"))
return
}
b.AddASN1(asn1.INTEGER, func(c *cryptobyte.Builder) {
if bytes[0]&0x80 != 0 {
c.AddUint8(0)
}
c.AddBytes(bytes)
})
}

// https://github.com/golang/go/blob/master/src/crypto/ecdsa/ecdsa.go#L549-L560
func parseSignature(sig []byte) (r, s []byte, err error) {
var inner cryptobyte.String
input := cryptobyte.String(sig)
if !input.ReadASN1(&inner, asn1.SEQUENCE) ||
!input.Empty() ||
!inner.ReadASN1Integer(&r) ||
!inner.ReadASN1Integer(&s) ||
!inner.Empty() {
return nil, nil, errors.New("invalid ASN.1")
}
return r, s, nil
}
106 changes: 106 additions & 0 deletions eckcdsa/key_marshal.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package eckcdsa

/**
FROM GO 1.21.6 SOURCE CODE
*/

import (
"crypto/x509/pkix"
"encoding/asn1"
"errors"
)

func ParseECPrivateKey(der []byte) (*PrivateKey, error) {
// https://github.com/golang/go/blob/go1.21.6/src/crypto/x509/sec1.go#L37-L39
return parseECPrivateKey(nil, der)
}
func (key *PrivateKey) MarshalECPrivateKey() ([]byte, error) {
// https://github.com/golang/go/blob/go1.21.6/src/crypto/x509/sec1.go#L46-L53
oid, ok := oidFromNamedCurve(key.Curve)
if !ok {
return nil, errors.New("eckcdsa: unknown elliptic curve")
}

return marshalECPrivateKeyWithOID(key, oid)
}

func ParsePKCS8PrivateKey(der []byte) (key *PrivateKey, err error) {
// https://github.com/golang/go/blob/go1.21.6/src/crypto/x509/pkcs8.go#L35-L45
var privKey pkcs8
if _, err := asn1.Unmarshal(der, &privKey); err != nil {
if _, err := asn1.Unmarshal(der, &ecPrivateKey{}); err == nil {
return nil, errors.New("eckcdsa: failed to parse private key (use ParseECPrivateKey instead for this key format)")
}
return nil, err
}

// https://github.com/golang/go/blob/go1.21.6/src/crypto/x509/pkcs8.go#L54-L64
bytes := privKey.Algo.Parameters.FullBytes
namedCurveOID := new(asn1.ObjectIdentifier)
if _, err := asn1.Unmarshal(bytes, namedCurveOID); err != nil {
namedCurveOID = nil
}
key, err = parseECPrivateKey(namedCurveOID, privKey.PrivateKey)
if err != nil {
return nil, errors.New("eckcdsa: failed to parse EC private key embedded in PKCS#8: " + err.Error())
}
return key, nil
}
func (k *PrivateKey) MarshalPKCS8PrivateKey() ([]byte, error) {
// https://github.com/golang/go/blob/go1.21.6/src/crypto/x509/pkcs8.go#L101-L102
var privKey pkcs8

// https://github.com/golang/go/blob/go1.21.6/src/crypto/x509/pkcs8.go#L112-L129
oid, ok := oidFromNamedCurve(k.Curve)
if !ok {
return nil, errors.New("eckcdsa: unknown curve while marshaling to PKCS#8")
}
oidBytes, err := asn1.Marshal(oid)
if err != nil {
return nil, errors.New("eckcdsa: failed to marshal curve OID: " + err.Error())
}
privKey.Algo = pkix.AlgorithmIdentifier{
Algorithm: oidPublicKeyECDSA,
Parameters: asn1.RawValue{
FullBytes: oidBytes,
},
}
if privKey.PrivateKey, err = marshalECPrivateKeyWithOID(k, nil); err != nil {
return nil, errors.New("eckcdsa: failed to marshal EC private key while building PKCS#8: " + err.Error())
}

// https://github.com/golang/go/blob/go1.21.6/src/crypto/x509/pkcs8.go#L174C2-L174C30
return asn1.Marshal(privKey)
}

func ParsePKIXPublicKey(derBytes []byte) (key *PublicKey, err error) {
// https://github.com/golang/go/blob/go1.21.6/src/crypto/x509/x509.go#L71-L82
var pki publicKeyInfo
if rest, err := asn1.Unmarshal(derBytes, &pki); err != nil {
return nil, err
} else if len(rest) != 0 {
return nil, errors.New("eckcdsa: trailing data after ASN.1 of public-key")
}
return parsePublicKey(&pki)
}
func (pub *PublicKey) MarshalPKIXPublicKey() ([]byte, error) {
// https://github.com/golang/go/blob/go1.21.6/src/crypto/x509/x509.go#L150-L169
var publicKeyBytes []byte
var publicKeyAlgorithm pkix.AlgorithmIdentifier
var err error

if publicKeyBytes, publicKeyAlgorithm, err = marshalPublicKey(pub); err != nil {
return nil, err
}

pkix := pkixPublicKey{
Algo: publicKeyAlgorithm,
BitString: asn1.BitString{
Bytes: publicKeyBytes,
BitLength: 8 * len(publicKeyBytes),
},
}

ret, _ := asn1.Marshal(pkix)
return ret, nil
}
101 changes: 101 additions & 0 deletions eckcdsa/key_marshal_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package eckcdsa

import (
"crypto/elliptic"
"crypto/rand"
"testing"
)

var (
curveList = []elliptic.Curve{
elliptic.P224(),
elliptic.P256(),
elliptic.P384(),
elliptic.P521(),
}

testCases []struct {
PrivateKey *PrivateKey
Marshaled []byte
}
)

func TestPKIXPublicKey(t *testing.T) {
for _, curve := range curveList {
p1p, _ := GenerateKey(curve, rand.Reader)
p1 := p1p.PublicKey

der, err := p1.MarshalPKIXPublicKey()
if err != nil {
t.Error(err)
return
}

p2, err := ParsePKIXPublicKey(der)
if err != nil {
t.Error(err)
return
}

if !p1.Equal(p2) {
t.Error("not equals!")
return
}
}
}
func TestMarshal(t *testing.T) {
for _, curve := range curveList {
p1, _ := GenerateKey(curve, rand.Reader)

der, err := p1.MarshalECPrivateKey()
if err != nil {
t.Error(err)
return
}

p2, err := ParseECPrivateKey(der)
if err != nil {
t.Error(err)
return
}

if !p1.Equal(p2) {
t.Error("not equals!")
return
}
}
}
func TestPKCS8PrivateKey(t *testing.T) {
for _, curve := range curveList {
p1, _ := GenerateKey(curve, rand.Reader)

der, err := p1.MarshalPKCS8PrivateKey()
if err != nil {
t.Error(err)
return
}

p2, err := ParsePKCS8PrivateKey(der)
if err != nil {
t.Error(err)
return
}

if !p1.Equal(p2) {
t.Error("not equals!")
return
}
}
}

func TestParseECPrivateKey(t *testing.T) {
}
func TestParsePKCS8PrivateKey(t *testing.T) {
}
func TestMarshalECPrivateKey(t *testing.T) {
}
func TestMarshalPKCS8PrivateKey(t *testing.T) {
}
func TestMarshalPKIXPublicKey(t *testing.T) {

}
Loading

0 comments on commit 07200b9

Please sign in to comment.