mirror of https://github.com/golang/go.git
Compare commits
6 Commits
66d51bd293
...
357571e787
| Author | SHA1 | Date |
|---|---|---|
|
|
357571e787 | |
|
|
49cdf0c42e | |
|
|
3bf1eecbd3 | |
|
|
8ed23a2936 | |
|
|
ef60769b46 | |
|
|
fa2ee19f65 |
|
|
@ -82,7 +82,7 @@ func newGCM(cipher Block, nonceSize, tagSize int) (AEAD, error) {
|
||||||
|
|
||||||
// NewGCMWithRandomNonce returns the given cipher wrapped in Galois Counter
|
// NewGCMWithRandomNonce returns the given cipher wrapped in Galois Counter
|
||||||
// Mode, with randomly-generated nonces. The cipher must have been created by
|
// Mode, with randomly-generated nonces. The cipher must have been created by
|
||||||
// [aes.NewCipher].
|
// [crypto/aes.NewCipher].
|
||||||
//
|
//
|
||||||
// It generates a random 96-bit nonce, which is prepended to the ciphertext by Seal,
|
// It generates a random 96-bit nonce, which is prepended to the ciphertext by Seal,
|
||||||
// and is extracted from the ciphertext by Open. The NonceSize of the AEAD is zero,
|
// and is extracted from the ciphertext by Open. The NonceSize of the AEAD is zero,
|
||||||
|
|
|
||||||
|
|
@ -1038,11 +1038,14 @@ func parseCertificate(der []byte) (*Certificate, error) {
|
||||||
if !spki.ReadASN1BitString(&spk) {
|
if !spki.ReadASN1BitString(&spk) {
|
||||||
return nil, errors.New("x509: malformed subjectPublicKey")
|
return nil, errors.New("x509: malformed subjectPublicKey")
|
||||||
}
|
}
|
||||||
if cert.PublicKeyAlgorithm != UnknownPublicKeyAlgorithm {
|
pki := &publicKeyInfo{
|
||||||
cert.PublicKey, err = parsePublicKey(&publicKeyInfo{
|
Algorithm: pkAI,
|
||||||
Algorithm: pkAI,
|
PublicKey: spk,
|
||||||
PublicKey: spk,
|
}
|
||||||
})
|
if cert.PublicKeyAlgorithm == UnknownPublicKeyAlgorithm {
|
||||||
|
cert.PublicKey = pki
|
||||||
|
} else {
|
||||||
|
cert.PublicKey, err = parsePublicKey(pki)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -190,8 +190,8 @@ func verifyChain(c *Certificate, chainCtx *syscall.CertChainContext, opts *Verif
|
||||||
if parent.PublicKeyAlgorithm != ECDSA {
|
if parent.PublicKeyAlgorithm != ECDSA {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if err := parent.CheckSignature(chain[i].SignatureAlgorithm,
|
if err := checkSignature(chain[i].SignatureAlgorithm,
|
||||||
chain[i].RawTBSCertificate, chain[i].Signature); err != nil {
|
chain[i].RawTBSCertificate, chain[i].Signature, parent.PublicKey, true, opts); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -218,6 +218,10 @@ type VerifyOptions struct {
|
||||||
// field implies any valid policy is acceptable.
|
// field implies any valid policy is acceptable.
|
||||||
CertificatePolicies []OID
|
CertificatePolicies []OID
|
||||||
|
|
||||||
|
// UnknownAlgorithmVerifier specifies a callback to use to verify
|
||||||
|
// a signature with an unknown AlgorithmIdentifier.
|
||||||
|
UnknownAlgorithmVerifier func(alg pkix.AlgorithmIdentifier, signed, signature, pk []byte) error
|
||||||
|
|
||||||
// The following policy fields are unexported, because we do not expect
|
// The following policy fields are unexported, because we do not expect
|
||||||
// users to actually need to use them, but are useful for testing the
|
// users to actually need to use them, but are useful for testing the
|
||||||
// policy validation code.
|
// policy validation code.
|
||||||
|
|
@ -975,7 +979,7 @@ func (c *Certificate) buildChains(currentChain []*Certificate, sigChecks *int, o
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.CheckSignatureFrom(candidate.cert); err != nil {
|
if err := c.checkSignatureFrom(candidate.cert, opts); err != nil {
|
||||||
if hintErr == nil {
|
if hintErr == nil {
|
||||||
hintErr = err
|
hintErr = err
|
||||||
hintCert = candidate.cert
|
hintCert = candidate.cert
|
||||||
|
|
|
||||||
|
|
@ -205,6 +205,17 @@ type publicKeyInfo struct {
|
||||||
PublicKey asn1.BitString
|
PublicKey asn1.BitString
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (pki *publicKeyInfo) Equal(other crypto.PublicKey) bool {
|
||||||
|
pki2, ok := other.(*publicKeyInfo)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return (pki.Algorithm.Algorithm.Equal(pki2.Algorithm.Algorithm) &&
|
||||||
|
bytes.Equal(pki.Algorithm.Parameters.FullBytes, pki2.Algorithm.Parameters.FullBytes) &&
|
||||||
|
pki.PublicKey.BitLength == pki2.PublicKey.BitLength &&
|
||||||
|
bytes.Equal(pki.PublicKey.Bytes, pki2.PublicKey.Bytes))
|
||||||
|
}
|
||||||
|
|
||||||
// RFC 5280, 4.2.1.1
|
// RFC 5280, 4.2.1.1
|
||||||
type authKeyId struct {
|
type authKeyId struct {
|
||||||
Id []byte `asn1:"optional,tag:0"`
|
Id []byte `asn1:"optional,tag:0"`
|
||||||
|
|
@ -909,6 +920,10 @@ func (c *Certificate) hasSANExtension() bool {
|
||||||
// This is a low-level API that performs very limited checks, and not a full
|
// This is a low-level API that performs very limited checks, and not a full
|
||||||
// path verifier. Most users should use [Certificate.Verify] instead.
|
// path verifier. Most users should use [Certificate.Verify] instead.
|
||||||
func (c *Certificate) CheckSignatureFrom(parent *Certificate) error {
|
func (c *Certificate) CheckSignatureFrom(parent *Certificate) error {
|
||||||
|
return c.checkSignatureFrom(parent, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Certificate) checkSignatureFrom(parent *Certificate, opts *VerifyOptions) error {
|
||||||
// RFC 5280, 4.2.1.9:
|
// RFC 5280, 4.2.1.9:
|
||||||
// "If the basic constraints extension is not present in a version 3
|
// "If the basic constraints extension is not present in a version 3
|
||||||
// certificate, or the extension is present but the cA boolean is not
|
// certificate, or the extension is present but the cA boolean is not
|
||||||
|
|
@ -923,11 +938,7 @@ func (c *Certificate) CheckSignatureFrom(parent *Certificate) error {
|
||||||
return ConstraintViolationError{}
|
return ConstraintViolationError{}
|
||||||
}
|
}
|
||||||
|
|
||||||
if parent.PublicKeyAlgorithm == UnknownPublicKeyAlgorithm {
|
return checkSignature(c.SignatureAlgorithm, c.RawTBSCertificate, c.Signature, parent.PublicKey, false, opts)
|
||||||
return ErrUnsupportedAlgorithm
|
|
||||||
}
|
|
||||||
|
|
||||||
return checkSignature(c.SignatureAlgorithm, c.RawTBSCertificate, c.Signature, parent.PublicKey, false)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CheckSignature verifies that signature is a valid signature over signed from
|
// CheckSignature verifies that signature is a valid signature over signed from
|
||||||
|
|
@ -938,7 +949,7 @@ func (c *Certificate) CheckSignatureFrom(parent *Certificate) error {
|
||||||
// [MD5WithRSA] signatures are rejected, while [SHA1WithRSA] and [ECDSAWithSHA1]
|
// [MD5WithRSA] signatures are rejected, while [SHA1WithRSA] and [ECDSAWithSHA1]
|
||||||
// signatures are currently accepted.
|
// signatures are currently accepted.
|
||||||
func (c *Certificate) CheckSignature(algo SignatureAlgorithm, signed, signature []byte) error {
|
func (c *Certificate) CheckSignature(algo SignatureAlgorithm, signed, signature []byte) error {
|
||||||
return checkSignature(algo, signed, signature, c.PublicKey, true)
|
return checkSignature(algo, signed, signature, c.PublicKey, true, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Certificate) hasNameConstraints() bool {
|
func (c *Certificate) hasNameConstraints() bool {
|
||||||
|
|
@ -960,10 +971,24 @@ func signaturePublicKeyAlgoMismatchError(expectedPubKeyAlgo PublicKeyAlgorithm,
|
||||||
|
|
||||||
// checkSignature verifies that signature is a valid signature over signed from
|
// checkSignature verifies that signature is a valid signature over signed from
|
||||||
// a crypto.PublicKey.
|
// a crypto.PublicKey.
|
||||||
func checkSignature(algo SignatureAlgorithm, signed, signature []byte, publicKey crypto.PublicKey, allowSHA1 bool) (err error) {
|
func checkSignature(algo SignatureAlgorithm, signed, signature []byte, publicKey crypto.PublicKey, allowSHA1 bool, opts *VerifyOptions) (err error) {
|
||||||
var hashType crypto.Hash
|
var hashType crypto.Hash
|
||||||
var pubKeyAlgo PublicKeyAlgorithm
|
var pubKeyAlgo PublicKeyAlgorithm
|
||||||
|
|
||||||
|
if algo == UnknownSignatureAlgorithm {
|
||||||
|
pki, ok := publicKey.(*publicKeyInfo)
|
||||||
|
if !ok || opts == nil || opts.UnknownAlgorithmVerifier == nil {
|
||||||
|
return ErrUnsupportedAlgorithm
|
||||||
|
}
|
||||||
|
|
||||||
|
return opts.UnknownAlgorithmVerifier(
|
||||||
|
pki.Algorithm,
|
||||||
|
signed,
|
||||||
|
signature,
|
||||||
|
pki.PublicKey.Bytes,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
for _, details := range signatureAlgorithmDetails {
|
for _, details := range signatureAlgorithmDetails {
|
||||||
if details.algo == algo {
|
if details.algo == algo {
|
||||||
hashType = details.hash
|
hashType = details.hash
|
||||||
|
|
@ -1585,7 +1610,7 @@ func signTBS(tbs []byte, key crypto.Signer, sigAlg SignatureAlgorithm, rand io.R
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the signature to ensure the crypto.Signer behaved correctly.
|
// Check the signature to ensure the crypto.Signer behaved correctly.
|
||||||
if err := checkSignature(sigAlg, tbs, signature, key.Public(), true); err != nil {
|
if err := checkSignature(sigAlg, tbs, signature, key.Public(), true, nil); err != nil {
|
||||||
return nil, fmt.Errorf("x509: signature returned by signer is invalid: %w", err)
|
return nil, fmt.Errorf("x509: signature returned by signer is invalid: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2259,7 +2284,7 @@ func parseCertificateRequest(in *certificateRequest) (*CertificateRequest, error
|
||||||
|
|
||||||
// CheckSignature reports whether the signature on c is valid.
|
// CheckSignature reports whether the signature on c is valid.
|
||||||
func (c *CertificateRequest) CheckSignature() error {
|
func (c *CertificateRequest) CheckSignature() error {
|
||||||
return checkSignature(c.SignatureAlgorithm, c.RawTBSCertificateRequest, c.Signature, c.PublicKey, true)
|
return checkSignature(c.SignatureAlgorithm, c.RawTBSCertificateRequest, c.Signature, c.PublicKey, true, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RevocationListEntry represents an entry in the revokedCertificates
|
// RevocationListEntry represents an entry in the revokedCertificates
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
//
|
||||||
|
PACKAGE issue62640
|
||||||
|
|
||||||
|
IMPORTPATH
|
||||||
|
testdata/issue62640
|
||||||
|
|
||||||
|
FILENAMES
|
||||||
|
testdata/issue62640.go
|
||||||
|
|
||||||
|
TYPES
|
||||||
|
//
|
||||||
|
type E struct{}
|
||||||
|
|
||||||
|
// F should be hidden within S because of the S.F field.
|
||||||
|
func (E) F()
|
||||||
|
|
||||||
|
//
|
||||||
|
type S struct {
|
||||||
|
E
|
||||||
|
F int
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
//
|
||||||
|
PACKAGE issue62640
|
||||||
|
|
||||||
|
IMPORTPATH
|
||||||
|
testdata/issue62640
|
||||||
|
|
||||||
|
FILENAMES
|
||||||
|
testdata/issue62640.go
|
||||||
|
|
||||||
|
TYPES
|
||||||
|
//
|
||||||
|
type E struct{}
|
||||||
|
|
||||||
|
// F should be hidden within S because of the S.F field.
|
||||||
|
func (E) F()
|
||||||
|
|
||||||
|
//
|
||||||
|
type S struct {
|
||||||
|
E
|
||||||
|
F int
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
//
|
||||||
|
PACKAGE issue62640
|
||||||
|
|
||||||
|
IMPORTPATH
|
||||||
|
testdata/issue62640
|
||||||
|
|
||||||
|
FILENAMES
|
||||||
|
testdata/issue62640.go
|
||||||
|
|
||||||
|
TYPES
|
||||||
|
//
|
||||||
|
type E struct{}
|
||||||
|
|
||||||
|
// F should be hidden within S because of the S.F field.
|
||||||
|
func (E) F()
|
||||||
|
|
||||||
|
//
|
||||||
|
type S struct {
|
||||||
|
E
|
||||||
|
F int
|
||||||
|
}
|
||||||
|
|
||||||
|
// F should be hidden within S because of the S.F field.
|
||||||
|
func (S) F()
|
||||||
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
// Copyright 2025 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 issue62640
|
||||||
|
|
||||||
|
type E struct{}
|
||||||
|
|
||||||
|
// F should be hidden within S because of the S.F field.
|
||||||
|
func (E) F() {}
|
||||||
|
|
||||||
|
type S struct {
|
||||||
|
E
|
||||||
|
F int
|
||||||
|
}
|
||||||
|
|
@ -312,8 +312,10 @@ type heapArena struct {
|
||||||
// during marking.
|
// during marking.
|
||||||
pageSpecials [pagesPerArena / 8]uint8
|
pageSpecials [pagesPerArena / 8]uint8
|
||||||
|
|
||||||
// pageUseSpanDartboard is a bitmap that indicates which spans are
|
// pageUseSpanInlineMarkBits is a bitmap where each bit corresponds
|
||||||
// heap spans and also gcUsesSpanDartboard.
|
// to a span, as only spans one page in size can have inline mark bits.
|
||||||
|
// The bit indicates that the span has a spanInlineMarkBits struct
|
||||||
|
// stored directly at the top end of the span's memory.
|
||||||
pageUseSpanInlineMarkBits [pagesPerArena / 8]uint8
|
pageUseSpanInlineMarkBits [pagesPerArena / 8]uint8
|
||||||
|
|
||||||
// checkmarks stores the debug.gccheckmark state. It is only
|
// checkmarks stores the debug.gccheckmark state. It is only
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
// Copyright 2025 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 synctest_test
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
// helperLog is a t.Helper which logs.
|
||||||
|
// Since it is a helper, the log prefix should contain
|
||||||
|
// the caller's file, not helper_test.go.
|
||||||
|
func helperLog(t *testing.T, s string) {
|
||||||
|
t.Helper()
|
||||||
|
t.Log(s)
|
||||||
|
}
|
||||||
|
|
@ -140,6 +140,18 @@ func TestRun(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestHelper(t *testing.T) {
|
||||||
|
runTest(t, []string{"-test.v"}, func() {
|
||||||
|
synctest.Test(t, func(t *testing.T) {
|
||||||
|
helperLog(t, "log in helper")
|
||||||
|
})
|
||||||
|
}, `^=== RUN TestHelper
|
||||||
|
synctest_test.go:.* log in helper
|
||||||
|
--- PASS: TestHelper.*
|
||||||
|
PASS
|
||||||
|
$`)
|
||||||
|
}
|
||||||
|
|
||||||
func wantPanic(t *testing.T, want string) {
|
func wantPanic(t *testing.T, want string) {
|
||||||
if e := recover(); e != nil {
|
if e := recover(); e != nil {
|
||||||
if got := fmt.Sprint(e); got != want {
|
if got := fmt.Sprint(e); got != want {
|
||||||
|
|
|
||||||
|
|
@ -1261,6 +1261,9 @@ func (c *common) Skipped() bool {
|
||||||
// When printing file and line information, that function will be skipped.
|
// When printing file and line information, that function will be skipped.
|
||||||
// Helper may be called simultaneously from multiple goroutines.
|
// Helper may be called simultaneously from multiple goroutines.
|
||||||
func (c *common) Helper() {
|
func (c *common) Helper() {
|
||||||
|
if c.isSynctest {
|
||||||
|
c = c.parent
|
||||||
|
}
|
||||||
c.mu.Lock()
|
c.mu.Lock()
|
||||||
defer c.mu.Unlock()
|
defer c.mu.Unlock()
|
||||||
if c.helperPCs == nil {
|
if c.helperPCs == nil {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue