Compare commits
10
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9e8e0b3908 | ||
|
|
84dcc777aa | ||
|
|
7f63de1d35 | ||
|
|
c90954cbb9 | ||
|
|
eb9a90e9f9 | ||
|
|
afb6bcd081 | ||
|
|
5c72a88397 | ||
|
|
123391ffb6 | ||
|
|
948cd5f358 | ||
|
|
ab33eee955 |
@@ -0,0 +1,176 @@
|
||||
// Copyright 2020 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package wycheproof
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/crypto/chacha20poly1305"
|
||||
)
|
||||
|
||||
func TestAEAD(t *testing.T) {
|
||||
// AeadTestVector
|
||||
type AeadTestVector struct {
|
||||
|
||||
// additional authenticated data
|
||||
Aad string `json:"aad,omitempty"`
|
||||
|
||||
// A brief description of the test case
|
||||
Comment string `json:"comment,omitempty"`
|
||||
|
||||
// the ciphertext (without iv and tag)
|
||||
Ct string `json:"ct,omitempty"`
|
||||
|
||||
// A list of flags
|
||||
Flags []string `json:"flags,omitempty"`
|
||||
|
||||
// the nonce
|
||||
Iv string `json:"iv,omitempty"`
|
||||
|
||||
// the key
|
||||
Key string `json:"key,omitempty"`
|
||||
|
||||
// the plaintext
|
||||
Msg string `json:"msg,omitempty"`
|
||||
|
||||
// Test result
|
||||
Result string `json:"result,omitempty"`
|
||||
|
||||
// the authentication tag
|
||||
Tag string `json:"tag,omitempty"`
|
||||
|
||||
// Identifier of the test case
|
||||
TcId int `json:"tcId,omitempty"`
|
||||
}
|
||||
|
||||
// Notes a description of the labels used in the test vectors
|
||||
type Notes struct {
|
||||
}
|
||||
|
||||
// AeadTestGroup
|
||||
type AeadTestGroup struct {
|
||||
|
||||
// the IV size in bits
|
||||
IvSize int `json:"ivSize,omitempty"`
|
||||
|
||||
// the keySize in bits
|
||||
KeySize int `json:"keySize,omitempty"`
|
||||
|
||||
// the expected size of the tag in bits
|
||||
TagSize int `json:"tagSize,omitempty"`
|
||||
Tests []*AeadTestVector `json:"tests,omitempty"`
|
||||
Type interface{} `json:"type,omitempty"`
|
||||
}
|
||||
|
||||
// Root
|
||||
type Root struct {
|
||||
|
||||
// the primitive tested in the test file
|
||||
Algorithm string `json:"algorithm,omitempty"`
|
||||
|
||||
// the version of the test vectors.
|
||||
GeneratorVersion string `json:"generatorVersion,omitempty"`
|
||||
|
||||
// additional documentation
|
||||
Header []string `json:"header,omitempty"`
|
||||
|
||||
// a description of the labels used in the test vectors
|
||||
Notes *Notes `json:"notes,omitempty"`
|
||||
|
||||
// the number of test vectors in this test
|
||||
NumberOfTests int `json:"numberOfTests,omitempty"`
|
||||
Schema interface{} `json:"schema,omitempty"`
|
||||
TestGroups []*AeadTestGroup `json:"testGroups,omitempty"`
|
||||
}
|
||||
|
||||
testSealOpen := func(t *testing.T, aead cipher.AEAD, tv *AeadTestVector, recoverBadNonce func()) {
|
||||
defer recoverBadNonce()
|
||||
|
||||
iv, tag, ct, msg, aad := decodeHex(tv.Iv), decodeHex(tv.Tag), decodeHex(tv.Ct), decodeHex(tv.Msg), decodeHex(tv.Aad)
|
||||
|
||||
genCT := aead.Seal(nil, iv, msg, aad)
|
||||
genMsg, err := aead.Open(nil, iv, genCT, aad)
|
||||
if err != nil {
|
||||
t.Errorf("failed to decrypt generated ciphertext: %s", err)
|
||||
}
|
||||
if !bytes.Equal(genMsg, msg) {
|
||||
t.Errorf("unexpected roundtripped plaintext: got %x, want %x", genMsg, msg)
|
||||
}
|
||||
|
||||
ctWithTag := append(ct, tag...)
|
||||
msg2, err := aead.Open(nil, iv, ctWithTag, aad)
|
||||
wantPass := shouldPass(tv.Result, tv.Flags, nil)
|
||||
if !wantPass && err == nil {
|
||||
t.Error("decryption succeeded when it should've failed")
|
||||
} else if wantPass {
|
||||
if err != nil {
|
||||
t.Fatalf("decryption failed: %s", err)
|
||||
}
|
||||
if !bytes.Equal(genCT, ctWithTag) {
|
||||
t.Errorf("generated ciphertext doesn't match expected: got %x, want %x", genCT, ctWithTag)
|
||||
}
|
||||
if !bytes.Equal(msg, msg2) {
|
||||
t.Errorf("decrypted ciphertext doesn't match expected: got %x, want %x", msg2, msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vectors := map[string]func(*testing.T, []byte) cipher.AEAD{
|
||||
"aes_gcm_test.json": func(t *testing.T, key []byte) cipher.AEAD {
|
||||
aesCipher, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to construct cipher: %s", err)
|
||||
}
|
||||
aead, err := cipher.NewGCM(aesCipher)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to construct cipher: %s", err)
|
||||
}
|
||||
return aead
|
||||
},
|
||||
"chacha20_poly1305_test.json": func(t *testing.T, key []byte) cipher.AEAD {
|
||||
aead, err := chacha20poly1305.New(key)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to construct cipher: %s", err)
|
||||
}
|
||||
return aead
|
||||
},
|
||||
"xchacha20_poly1305_test.json": func(t *testing.T, key []byte) cipher.AEAD {
|
||||
aead, err := chacha20poly1305.NewX(key)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to construct cipher: %s", err)
|
||||
}
|
||||
return aead
|
||||
},
|
||||
}
|
||||
for file, cipherInit := range vectors {
|
||||
var root Root
|
||||
readTestVector(t, file, &root)
|
||||
for _, tg := range root.TestGroups {
|
||||
for _, tv := range tg.Tests {
|
||||
testName := fmt.Sprintf("%s #%d", file, tv.TcId)
|
||||
if tv.Comment != "" {
|
||||
testName += fmt.Sprintf(" %s", tv.Comment)
|
||||
}
|
||||
t.Run(testName, func(t *testing.T) {
|
||||
aead := cipherInit(t, decodeHex(tv.Key))
|
||||
testSealOpen(t, aead, tv, func() {
|
||||
// A bad nonce causes a panic in AEAD.Seal and AEAD.Open,
|
||||
// so should be recovered. Fail the test if it broke for
|
||||
// some other reason.
|
||||
if r := recover(); r != nil {
|
||||
if tg.IvSize/8 == aead.NonceSize() {
|
||||
t.Error("unexpected panic")
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,148 +0,0 @@
|
||||
// Copyright 2019 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package wycheproof
|
||||
|
||||
import (
|
||||
"crypto/cipher"
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/crypto/chacha20poly1305"
|
||||
)
|
||||
|
||||
func TestChaCha20Poly1305(t *testing.T) {
|
||||
// AeadTestVector
|
||||
type AeadTestVector struct {
|
||||
|
||||
// additional authenticated data
|
||||
Aad string `json:"aad,omitempty"`
|
||||
|
||||
// A brief description of the test case
|
||||
Comment string `json:"comment,omitempty"`
|
||||
|
||||
// the ciphertext (without iv and tag)
|
||||
Ct string `json:"ct,omitempty"`
|
||||
|
||||
// A list of flags
|
||||
Flags []string `json:"flags,omitempty"`
|
||||
|
||||
// the nonce
|
||||
Iv string `json:"iv,omitempty"`
|
||||
|
||||
// the key
|
||||
Key string `json:"key,omitempty"`
|
||||
|
||||
// the plaintext
|
||||
Msg string `json:"msg,omitempty"`
|
||||
|
||||
// Test result
|
||||
Result string `json:"result,omitempty"`
|
||||
|
||||
// the authentication tag
|
||||
Tag string `json:"tag,omitempty"`
|
||||
|
||||
// Identifier of the test case
|
||||
TcId int `json:"tcId,omitempty"`
|
||||
}
|
||||
|
||||
// Notes a description of the labels used in the test vectors
|
||||
type Notes struct {
|
||||
}
|
||||
|
||||
// AeadTestGroup
|
||||
type AeadTestGroup struct {
|
||||
|
||||
// the IV size in bits
|
||||
IvSize int `json:"ivSize,omitempty"`
|
||||
|
||||
// the keySize in bits
|
||||
KeySize int `json:"keySize,omitempty"`
|
||||
|
||||
// the expected size of the tag in bits
|
||||
TagSize int `json:"tagSize,omitempty"`
|
||||
Tests []*AeadTestVector `json:"tests,omitempty"`
|
||||
Type interface{} `json:"type,omitempty"`
|
||||
}
|
||||
|
||||
// Root
|
||||
type Root struct {
|
||||
|
||||
// the primitive tested in the test file
|
||||
Algorithm string `json:"algorithm,omitempty"`
|
||||
|
||||
// the version of the test vectors.
|
||||
GeneratorVersion string `json:"generatorVersion,omitempty"`
|
||||
|
||||
// additional documentation
|
||||
Header []string `json:"header,omitempty"`
|
||||
|
||||
// a description of the labels used in the test vectors
|
||||
Notes *Notes `json:"notes,omitempty"`
|
||||
|
||||
// the number of test vectors in this test
|
||||
NumberOfTests int `json:"numberOfTests,omitempty"`
|
||||
Schema interface{} `json:"schema,omitempty"`
|
||||
TestGroups []*AeadTestGroup `json:"testGroups,omitempty"`
|
||||
}
|
||||
|
||||
testAeadSealOpen := func(t *testing.T, aead cipher.AEAD, tv *AeadTestVector, recoverBadNonce func()) {
|
||||
defer recoverBadNonce()
|
||||
|
||||
// Encrypt the message, then decrypt the new ciphertext and validate
|
||||
// the decrypted message.
|
||||
ciphertext := aead.Seal(nil, decodeHex(tv.Iv), decodeHex(tv.Msg), decodeHex(tv.Aad))
|
||||
msg, err := aead.Open(nil, decodeHex(tv.Iv), ciphertext, decodeHex(tv.Aad))
|
||||
if err != nil {
|
||||
t.Fatalf("#%d: decryption failed: %v", tv.TcId, err)
|
||||
}
|
||||
if got, want := hex.EncodeToString(msg), tv.Msg; got != want {
|
||||
t.Errorf("#%d: bad message after encrypting and decrypting: %s, want %v", tv.TcId, got, want)
|
||||
}
|
||||
|
||||
// Decrypt the provided ciphertext and validate the decrypted message.
|
||||
tv.Ct += tv.Tag // append the tag to the ciphertext
|
||||
msg2, err := aead.Open(nil, decodeHex(tv.Iv), decodeHex(tv.Ct), decodeHex(tv.Aad))
|
||||
wantPass := shouldPass(tv.Result, tv.Flags, nil)
|
||||
if wantPass {
|
||||
if err != nil {
|
||||
t.Errorf("#%d, type: %s, comment: %q, decryption wanted success, got err: %v", tv.TcId, tv.Result, tv.Comment, err)
|
||||
}
|
||||
if got, want := hex.EncodeToString(ciphertext), tv.Ct; got != want {
|
||||
t.Errorf("#%d: ciphertext doesn't match: %s, want=%s", tv.TcId, got, want)
|
||||
}
|
||||
if got, want := hex.EncodeToString(msg2), tv.Msg; got != want {
|
||||
t.Errorf("#%d: bad message after decrypting ciphertext: %s, want %v", tv.TcId, got, want)
|
||||
}
|
||||
} else {
|
||||
if err == nil {
|
||||
t.Errorf("#%d, type: %s, comment: %q, decryption wanted error", tv.TcId, tv.Result, tv.Comment)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var root Root
|
||||
readTestVector(t, "chacha20_poly1305_test.json", &root)
|
||||
for _, tg := range root.TestGroups {
|
||||
for _, tv := range tg.Tests {
|
||||
aead, err := chacha20poly1305.New(decodeHex(tv.Key))
|
||||
if err != nil {
|
||||
t.Fatalf("#%d: %v", tv.TcId, err)
|
||||
}
|
||||
if tg.TagSize/8 != aead.Overhead() {
|
||||
t.Fatalf("#%d: bad tag length", tv.TcId)
|
||||
}
|
||||
testAeadSealOpen(t, aead, tv, func() {
|
||||
// A bad nonce causes a panic in AEAD.Seal and AEAD.Open,
|
||||
// so should be recovered. Fail the test if it broke for
|
||||
// some other reason.
|
||||
if r := recover(); r != nil {
|
||||
if tg.IvSize/8 == chacha20poly1305.NonceSize {
|
||||
t.Errorf("#%d: unexpected panic", tv.TcId)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
// Copyright 2020 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package wycheproof
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRSAOAEPDecrypt(t *testing.T) {
|
||||
// Notes a description of the labels used in the test vectors
|
||||
type Notes struct {
|
||||
}
|
||||
|
||||
// RsaesOaepTestVector
|
||||
type RsaesOaepTestVector struct {
|
||||
|
||||
// A brief description of the test case
|
||||
Comment string `json:"comment,omitempty"`
|
||||
|
||||
// An encryption of msg
|
||||
Ct string `json:"ct,omitempty"`
|
||||
|
||||
// A list of flags
|
||||
Flags []string `json:"flags,omitempty"`
|
||||
|
||||
// The label used for the encryption
|
||||
Label string `json:"label,omitempty"`
|
||||
|
||||
// The encrypted message
|
||||
Msg string `json:"msg,omitempty"`
|
||||
|
||||
// Test result
|
||||
Result string `json:"result,omitempty"`
|
||||
|
||||
// Identifier of the test case
|
||||
TcId int `json:"tcId,omitempty"`
|
||||
}
|
||||
|
||||
// RsaesOaepTestGroup
|
||||
type RsaesOaepTestGroup struct {
|
||||
|
||||
// The private exponent
|
||||
D string `json:"d,omitempty"`
|
||||
|
||||
// The public exponent
|
||||
E string `json:"e,omitempty"`
|
||||
|
||||
// the message generating function (e.g. MGF1)
|
||||
Mgf string `json:"mgf,omitempty"`
|
||||
|
||||
// The hash function used for the message generating function.
|
||||
MgfSha string `json:"mgfSha,omitempty"`
|
||||
|
||||
// The modulus of the key
|
||||
N string `json:"n,omitempty"`
|
||||
|
||||
// Pem encoded private key
|
||||
PrivateKeyPem string `json:"privateKeyPem,omitempty"`
|
||||
|
||||
// Pkcs 8 encoded private key.
|
||||
PrivateKeyPkcs8 string `json:"privateKeyPkcs8,omitempty"`
|
||||
|
||||
// The hash function for hashing the label.
|
||||
Sha string `json:"sha,omitempty"`
|
||||
Tests []*RsaesOaepTestVector `json:"tests,omitempty"`
|
||||
Type interface{} `json:"type,omitempty"`
|
||||
}
|
||||
|
||||
// Root
|
||||
type Root struct {
|
||||
|
||||
// the primitive tested in the test file
|
||||
Algorithm string `json:"algorithm,omitempty"`
|
||||
|
||||
// the version of the test vectors.
|
||||
GeneratorVersion string `json:"generatorVersion,omitempty"`
|
||||
|
||||
// additional documentation
|
||||
Header []string `json:"header,omitempty"`
|
||||
|
||||
// a description of the labels used in the test vectors
|
||||
Notes *Notes `json:"notes,omitempty"`
|
||||
|
||||
// the number of test vectors in this test
|
||||
NumberOfTests int `json:"numberOfTests,omitempty"`
|
||||
Schema interface{} `json:"schema,omitempty"`
|
||||
TestGroups []*RsaesOaepTestGroup `json:"testGroups,omitempty"`
|
||||
}
|
||||
|
||||
// rsa.DecryptOAEP doesn't support using a different hash for the
|
||||
// MGF and the label, so skip all of the test vectors that use
|
||||
// these unbalanced constructions. rsa_oaep_misc_test.json contains
|
||||
// both balanced and unbalanced constructions so in that case
|
||||
// we just filter out any test groups where MgfSha != Sha
|
||||
files := []string{
|
||||
"rsa_oaep_2048_sha1_mgf1sha1_test.json",
|
||||
"rsa_oaep_2048_sha224_mgf1sha224_test.json",
|
||||
"rsa_oaep_2048_sha256_mgf1sha256_test.json",
|
||||
"rsa_oaep_2048_sha384_mgf1sha384_test.json",
|
||||
"rsa_oaep_2048_sha512_mgf1sha512_test.json",
|
||||
"rsa_oaep_3072_sha256_mgf1sha256_test.json",
|
||||
"rsa_oaep_3072_sha512_mgf1sha512_test.json",
|
||||
"rsa_oaep_4096_sha256_mgf1sha256_test.json",
|
||||
"rsa_oaep_4096_sha512_mgf1sha512_test.json",
|
||||
"rsa_oaep_misc_test.json",
|
||||
}
|
||||
|
||||
flagsShouldPass := map[string]bool{
|
||||
// rsa.DecryptOAEP happily supports small key sizes
|
||||
"SmallModulus": true,
|
||||
}
|
||||
|
||||
for _, f := range files {
|
||||
var root Root
|
||||
readTestVector(t, f, &root)
|
||||
for _, tg := range root.TestGroups {
|
||||
if tg.MgfSha != tg.Sha {
|
||||
continue
|
||||
}
|
||||
priv, err := x509.ParsePKCS8PrivateKey(decodeHex(tg.PrivateKeyPkcs8))
|
||||
if err != nil {
|
||||
t.Fatalf("%s failed to parse PKCS #8 private key: %s", f, err)
|
||||
}
|
||||
hash := parseHash(tg.Sha)
|
||||
for _, tv := range tg.Tests {
|
||||
t.Run(fmt.Sprintf("%s #%d", f, tv.TcId), func(t *testing.T) {
|
||||
wantPass := shouldPass(tv.Result, tv.Flags, flagsShouldPass)
|
||||
plaintext, err := rsa.DecryptOAEP(hash.New(), nil, priv.(*rsa.PrivateKey), decodeHex(tv.Ct), decodeHex(tv.Label))
|
||||
if wantPass {
|
||||
if err != nil {
|
||||
t.Fatalf("comment: %s, expected success: %s", tv.Comment, err)
|
||||
}
|
||||
if !bytes.Equal(plaintext, decodeHex(tv.Msg)) {
|
||||
t.Errorf("comment: %s, unexpected plaintext: got %x, want %s", tv.Comment, plaintext, tv.Msg)
|
||||
}
|
||||
} else if err == nil {
|
||||
t.Errorf("comment: %s, expected failure", tv.Comment)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -40,7 +40,7 @@ const (
|
||||
func Sum(m []byte, key *[KeySize]byte) *[Size]byte {
|
||||
mac := hmac.New(sha512.New, key[:])
|
||||
mac.Write(m)
|
||||
out := new([KeySize]byte)
|
||||
out := new([Size]byte)
|
||||
copy(out[:], mac.Sum(nil)[:Size])
|
||||
return out
|
||||
}
|
||||
|
||||
+17
-12
@@ -445,10 +445,18 @@ func ParseRequest(bytes []byte) (*Request, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ParseResponse parses an OCSP response in DER form. It only supports
|
||||
// responses for a single certificate. If the response contains a certificate
|
||||
// then the signature over the response is checked. If issuer is not nil then
|
||||
// it will be used to validate the signature or embedded certificate.
|
||||
// ParseResponse parses an OCSP response in DER form. The response must contain
|
||||
// only one certificate status. To parse the status of a specific certificate
|
||||
// from a response which may contain multiple statuses, use ParseResponseForCert
|
||||
// instead.
|
||||
//
|
||||
// If the response contains an embedded certificate, then that certificate will
|
||||
// be used to verify the response signature. If the response contains an
|
||||
// embedded certificate and issuer is not nil, then issuer will be used to verify
|
||||
// the signature on the embedded certificate.
|
||||
//
|
||||
// If the response does not contain an embedded certificate and issuer is not
|
||||
// nil, then issuer will be used to verify the response signature.
|
||||
//
|
||||
// Invalid responses and parse failures will result in a ParseError.
|
||||
// Error responses will result in a ResponseError.
|
||||
@@ -456,14 +464,11 @@ func ParseResponse(bytes []byte, issuer *x509.Certificate) (*Response, error) {
|
||||
return ParseResponseForCert(bytes, nil, issuer)
|
||||
}
|
||||
|
||||
// ParseResponseForCert parses an OCSP response in DER form and searches for a
|
||||
// Response relating to cert. If such a Response is found and the OCSP response
|
||||
// contains a certificate then the signature over the response is checked. If
|
||||
// issuer is not nil then it will be used to validate the signature or embedded
|
||||
// certificate.
|
||||
//
|
||||
// Invalid responses and parse failures will result in a ParseError.
|
||||
// Error responses will result in a ResponseError.
|
||||
// ParseResponseForCert acts identically to ParseResponse, except it supports
|
||||
// parsing responses that contain multiple statuses. If the response contains
|
||||
// multiple statuses and cert is not nil, then ParseResponseForCert will return
|
||||
// the first status which contains a matching serial, otherwise it will return an
|
||||
// error. If cert is nil, then the first status in the response will be returned.
|
||||
func ParseResponseForCert(bytes []byte, cert, issuer *x509.Certificate) (*Response, error) {
|
||||
var resp responseASN1
|
||||
rest, err := asn1.Unmarshal(bytes, &resp)
|
||||
|
||||
+11
-1
@@ -30,6 +30,8 @@ var (
|
||||
oidFriendlyName = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 9, 20})
|
||||
oidLocalKeyID = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 9, 21})
|
||||
oidMicrosoftCSPName = asn1.ObjectIdentifier([]int{1, 3, 6, 1, 4, 1, 311, 17, 1})
|
||||
|
||||
errUnknownAttributeOID = errors.New("pkcs12: unknown attribute OID")
|
||||
)
|
||||
|
||||
type pfxPdu struct {
|
||||
@@ -104,6 +106,11 @@ func unmarshal(in []byte, out interface{}) error {
|
||||
}
|
||||
|
||||
// ToPEM converts all "safe bags" contained in pfxData to PEM blocks.
|
||||
// Unknown attributes are discarded.
|
||||
//
|
||||
// Note that although the returned PEM blocks for private keys have type
|
||||
// "PRIVATE KEY", the bytes are not encoded according to PKCS #8, but according
|
||||
// to PKCS #1 for RSA keys and SEC 1 for ECDSA keys.
|
||||
func ToPEM(pfxData []byte, password string) ([]*pem.Block, error) {
|
||||
encodedPassword, err := bmpString(password)
|
||||
if err != nil {
|
||||
@@ -135,6 +142,9 @@ func convertBag(bag *safeBag, password []byte) (*pem.Block, error) {
|
||||
|
||||
for _, attribute := range bag.Attributes {
|
||||
k, v, err := convertAttribute(&attribute)
|
||||
if err == errUnknownAttributeOID {
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -188,7 +198,7 @@ func convertAttribute(attribute *pkcs12Attribute) (key, value string, err error)
|
||||
key = "Microsoft CSP Name"
|
||||
isString = true
|
||||
default:
|
||||
return "", "", errors.New("pkcs12: unknown attribute with OID " + attribute.Id.String())
|
||||
return "", "", errUnknownAttributeOID
|
||||
}
|
||||
|
||||
if isString {
|
||||
|
||||
@@ -89,6 +89,9 @@ func ExampleToPEM() {
|
||||
var testdata = map[string]string{
|
||||
// 'null' password test case
|
||||
"Windows Azure Tools": `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`,
|
||||
// Windows IAS PEAP & LDAPS certificates test case
|
||||
// Unknown OID 1.3.6.1.4.1.311.17.2 should be dropped
|
||||
"Windows IAS PEAP & LDAPS certificates": `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`,
|
||||
// empty string password test case
|
||||
"testing@example.com": `MIIJzgIBAzCCCZQGCSqGSIb3DQEHAaCCCYUEggmBMIIJfTCCA/cGCSqGSIb3DQEHBqCCA+gwggPk
|
||||
AgEAMIID3QYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQYwDgQIIszfRGqcmPcCAggAgIIDsOZ9Eg1L
|
||||
|
||||
@@ -16,15 +16,6 @@ func (b *storageBuf) asBytes() *[maxRate]byte {
|
||||
return (*[maxRate]byte)(unsafe.Pointer(b))
|
||||
}
|
||||
|
||||
//go:nocheckptr
|
||||
//
|
||||
// xorInUnaligned intentionally reads the input buffer as an unaligned slice of
|
||||
// integers. The language spec is not clear on whether that is allowed.
|
||||
// See:
|
||||
// https://golang.org/issue/37644
|
||||
// https://golang.org/issue/37298
|
||||
// https://golang.org/issue/35381
|
||||
|
||||
// xorInUnaligned uses unaligned reads and writes to update d.a to contain d.a
|
||||
// XOR buf.
|
||||
func xorInUnaligned(d *state, buf []byte) {
|
||||
|
||||
+1
-1
@@ -471,7 +471,7 @@ func (cb KeyboardInteractiveChallenge) auth(session []byte, user string, c packe
|
||||
}
|
||||
|
||||
if len(answers) != len(prompts) {
|
||||
return authFailure, nil, errors.New("ssh: not enough answers from keyboard-interactive callback")
|
||||
return authFailure, nil, fmt.Errorf("ssh: incorrect number of answers from keyboard-interactive callback %d (expected %d)", len(answers), len(prompts))
|
||||
}
|
||||
responseLength := 1 + 4
|
||||
for _, a := range answers {
|
||||
|
||||
@@ -198,6 +198,7 @@ func ExampleDial() {
|
||||
if err != nil {
|
||||
log.Fatal("Failed to dial: ", err)
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
// Each ClientConn can support multiple interactive sessions,
|
||||
// represented by a Session.
|
||||
|
||||
+3
-10
@@ -557,8 +557,6 @@ type dhGEXSHA struct {
|
||||
hashFunc crypto.Hash
|
||||
}
|
||||
|
||||
const numMRTests = 64
|
||||
|
||||
const (
|
||||
dhGroupExchangeMinimumBits = 2048
|
||||
dhGroupExchangePreferredBits = 2048
|
||||
@@ -602,15 +600,8 @@ func (gex dhGEXSHA) Client(c packetConn, randSource io.Reader, magics *handshake
|
||||
gex.p = kexDHGexGroup.P
|
||||
gex.g = kexDHGexGroup.G
|
||||
|
||||
// Check if p is safe by verifing that p and (p-1)/2 are primes
|
||||
one := big.NewInt(1)
|
||||
var pHalf = &big.Int{}
|
||||
pHalf.Rsh(gex.p, 1)
|
||||
if !gex.p.ProbablyPrime(numMRTests) || !pHalf.ProbablyPrime(numMRTests) {
|
||||
return nil, fmt.Errorf("ssh: server provided gex p is not safe")
|
||||
}
|
||||
|
||||
// Check if g is safe by verifing that g > 1 and g < p - 1
|
||||
one := big.NewInt(1)
|
||||
var pMinusOne = &big.Int{}
|
||||
pMinusOne.Sub(gex.p, one)
|
||||
if gex.g.Cmp(one) != 1 && gex.g.Cmp(pMinusOne) != -1 {
|
||||
@@ -618,6 +609,8 @@ func (gex dhGEXSHA) Client(c packetConn, randSource io.Reader, magics *handshake
|
||||
}
|
||||
|
||||
// Send GexInit
|
||||
var pHalf = &big.Int{}
|
||||
pHalf.Rsh(gex.p, 1)
|
||||
x, err := rand.Int(randSource, pHalf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
Reference in New Issue
Block a user