mirror of
https://github.com/containers/skopeo.git
synced 2025-09-06 09:12:25 +00:00
Vendor in c/image with sigstore support
Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This commit is contained in:
14
vendor/github.com/sigstore/sigstore/COPYRIGHT.txt
generated
vendored
Normal file
14
vendor/github.com/sigstore/sigstore/COPYRIGHT.txt
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
|
||||
Copyright 2021 The Sigstore Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
202
vendor/github.com/sigstore/sigstore/LICENSE
generated
vendored
Normal file
202
vendor/github.com/sigstore/sigstore/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
170
vendor/github.com/sigstore/sigstore/pkg/cryptoutils/certificate.go
generated
vendored
Normal file
170
vendor/github.com/sigstore/sigstore/pkg/cryptoutils/certificate.go
generated
vendored
Normal file
@@ -0,0 +1,170 @@
|
||||
//
|
||||
// Copyright 2021 The Sigstore Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package cryptoutils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"math/big"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
// CertificatePEMType is the string "CERTIFICATE" to be used during PEM encoding and decoding
|
||||
CertificatePEMType PEMType = "CERTIFICATE"
|
||||
)
|
||||
|
||||
// MarshalCertificateToPEM converts the provided X509 certificate into PEM format
|
||||
func MarshalCertificateToPEM(cert *x509.Certificate) ([]byte, error) {
|
||||
if cert == nil {
|
||||
return nil, errors.New("nil certificate provided")
|
||||
}
|
||||
return PEMEncode(CertificatePEMType, cert.Raw), nil
|
||||
}
|
||||
|
||||
// MarshalCertificatesToPEM converts the provided X509 certificates into PEM format
|
||||
func MarshalCertificatesToPEM(certs []*x509.Certificate) ([]byte, error) {
|
||||
buf := bytes.Buffer{}
|
||||
for _, cert := range certs {
|
||||
pemBytes, err := MarshalCertificateToPEM(cert)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, _ = buf.Write(pemBytes)
|
||||
}
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
// UnmarshalCertificatesFromPEM extracts one or more X509 certificates from the provided
|
||||
// byte slice, which is assumed to be in PEM-encoded format.
|
||||
func UnmarshalCertificatesFromPEM(pemBytes []byte) ([]*x509.Certificate, error) {
|
||||
result := []*x509.Certificate{}
|
||||
remaining := pemBytes
|
||||
|
||||
for len(remaining) > 0 {
|
||||
var certDer *pem.Block
|
||||
certDer, remaining = pem.Decode(remaining)
|
||||
|
||||
if certDer == nil {
|
||||
return nil, errors.New("error during PEM decoding")
|
||||
}
|
||||
|
||||
cert, err := x509.ParseCertificate(certDer.Bytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result = append(result, cert)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// UnmarshalCertificatesFromPEMLimited extracts one or more X509 certificates from the provided
|
||||
// byte slice, which is assumed to be in PEM-encoded format. Fails after a specified
|
||||
// number of iterations. A reasonable limit is 10 iterations.
|
||||
func UnmarshalCertificatesFromPEMLimited(pemBytes []byte, iterations int) ([]*x509.Certificate, error) {
|
||||
result := []*x509.Certificate{}
|
||||
remaining := pemBytes
|
||||
|
||||
count := 0
|
||||
for len(remaining) > 0 {
|
||||
if count == iterations {
|
||||
return nil, errors.New("too many certificates specified in PEM block")
|
||||
}
|
||||
var certDer *pem.Block
|
||||
certDer, remaining = pem.Decode(remaining)
|
||||
|
||||
if certDer == nil {
|
||||
return nil, errors.New("error during PEM decoding")
|
||||
}
|
||||
|
||||
cert, err := x509.ParseCertificate(certDer.Bytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result = append(result, cert)
|
||||
count++
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// LoadCertificatesFromPEM extracts one or more X509 certificates from the provided
|
||||
// io.Reader.
|
||||
func LoadCertificatesFromPEM(pem io.Reader) ([]*x509.Certificate, error) {
|
||||
fileBytes, err := io.ReadAll(pem)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return UnmarshalCertificatesFromPEM(fileBytes)
|
||||
}
|
||||
|
||||
func formatTime(t time.Time) string {
|
||||
return t.UTC().Format(time.RFC3339)
|
||||
}
|
||||
|
||||
// CheckExpiration verifies that epoch is during the validity period of
|
||||
// the certificate provided.
|
||||
//
|
||||
// It returns nil if issueTime < epoch < expirationTime, and error otherwise.
|
||||
func CheckExpiration(cert *x509.Certificate, epoch time.Time) error {
|
||||
if cert == nil {
|
||||
return errors.New("certificate is nil")
|
||||
}
|
||||
if cert.NotAfter.Before(epoch) {
|
||||
return fmt.Errorf("certificate expiration time %s is before %s", formatTime(cert.NotAfter), formatTime(epoch))
|
||||
}
|
||||
if cert.NotBefore.After(epoch) {
|
||||
return fmt.Errorf("certificate issued time %s is before %s", formatTime(cert.NotBefore), formatTime(epoch))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ParseCSR parses a PKCS#10 PEM-encoded CSR.
|
||||
func ParseCSR(csr []byte) (*x509.CertificateRequest, error) {
|
||||
derBlock, _ := pem.Decode(csr)
|
||||
if derBlock == nil || derBlock.Bytes == nil {
|
||||
return nil, errors.New("no CSR found while decoding")
|
||||
}
|
||||
correctType := false
|
||||
acceptedHeaders := []string{"CERTIFICATE REQUEST", "NEW CERTIFICATE REQUEST"}
|
||||
for _, v := range acceptedHeaders {
|
||||
if derBlock.Type == v {
|
||||
correctType = true
|
||||
}
|
||||
}
|
||||
if !correctType {
|
||||
return nil, fmt.Errorf("DER type %v is not of any type %v for CSR", derBlock.Type, acceptedHeaders)
|
||||
}
|
||||
|
||||
return x509.ParseCertificateRequest(derBlock.Bytes)
|
||||
}
|
||||
|
||||
// GenerateSerialNumber creates a compliant serial number as per RFC 5280 4.1.2.2.
|
||||
// Serial numbers must be positive, and can be no longer than 20 bytes.
|
||||
// The serial number is generated with 159 bits, so that the first bit will always
|
||||
// be 0, resulting in a positive serial number.
|
||||
func GenerateSerialNumber() (*big.Int, error) {
|
||||
// Pick a random number from 0 to 2^159.
|
||||
serial, err := rand.Int(rand.Reader, (&big.Int{}).Exp(big.NewInt(2), big.NewInt(159), nil))
|
||||
if err != nil {
|
||||
return nil, errors.New("error generating serial number")
|
||||
}
|
||||
return serial, nil
|
||||
}
|
31
vendor/github.com/sigstore/sigstore/pkg/cryptoutils/generic.go
generated
vendored
Normal file
31
vendor/github.com/sigstore/sigstore/pkg/cryptoutils/generic.go
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
//
|
||||
// Copyright 2021 The Sigstore Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package cryptoutils
|
||||
|
||||
import (
|
||||
"encoding/pem"
|
||||
)
|
||||
|
||||
// PEMType is a specific type for string constants used during PEM encoding and decoding
|
||||
type PEMType string
|
||||
|
||||
// PEMEncode encodes the specified byte slice in PEM format using the provided type string
|
||||
func PEMEncode(typeStr PEMType, bytes []byte) []byte {
|
||||
return pem.EncodeToMemory(&pem.Block{
|
||||
Type: string(typeStr),
|
||||
Bytes: bytes,
|
||||
})
|
||||
}
|
96
vendor/github.com/sigstore/sigstore/pkg/cryptoutils/password.go
generated
vendored
Normal file
96
vendor/github.com/sigstore/sigstore/pkg/cryptoutils/password.go
generated
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
//
|
||||
// Copyright 2021 The Sigstore Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package cryptoutils
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"golang.org/x/term"
|
||||
)
|
||||
|
||||
// PassFunc is a type of function that takes a boolean (representing whether confirmation is desired) and returns the password as read, along with an error if one occurred
|
||||
type PassFunc func(bool) ([]byte, error)
|
||||
|
||||
var (
|
||||
// Read is for fuzzing
|
||||
Read = readPasswordFn
|
||||
)
|
||||
|
||||
// readPasswordFn reads the password from the following sources, in order of preference:
|
||||
//
|
||||
// - COSIGN_PASSWORD environment variable
|
||||
//
|
||||
// - user input from from terminal (if present)
|
||||
//
|
||||
// - provided to stdin from pipe
|
||||
func readPasswordFn() func() ([]byte, error) {
|
||||
if pw, ok := os.LookupEnv("COSIGN_PASSWORD"); ok {
|
||||
return func() ([]byte, error) {
|
||||
return []byte(pw), nil
|
||||
}
|
||||
}
|
||||
if term.IsTerminal(0) {
|
||||
return func() ([]byte, error) {
|
||||
return term.ReadPassword(0)
|
||||
}
|
||||
}
|
||||
// Handle piped in passwords.
|
||||
return func() ([]byte, error) {
|
||||
return ioutil.ReadAll(os.Stdin)
|
||||
}
|
||||
}
|
||||
|
||||
// StaticPasswordFunc returns a PassFunc which returns the provided password.
|
||||
func StaticPasswordFunc(pw []byte) PassFunc {
|
||||
return func(bool) ([]byte, error) {
|
||||
return pw, nil
|
||||
}
|
||||
}
|
||||
|
||||
// SkipPassword is a PassFunc that does not interact with a user, but
|
||||
// simply returns nil for both the password result and error struct.
|
||||
func SkipPassword(_ bool) ([]byte, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// GetPasswordFromStdIn gathers the password from stdin with an
|
||||
// optional confirmation step.
|
||||
func GetPasswordFromStdIn(confirm bool) ([]byte, error) {
|
||||
read := Read()
|
||||
fmt.Fprint(os.Stderr, "Enter password for private key: ")
|
||||
pw1, err := read()
|
||||
fmt.Fprintln(os.Stderr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !confirm {
|
||||
return pw1, nil
|
||||
}
|
||||
fmt.Fprint(os.Stderr, "Enter again: ")
|
||||
pw2, err := read()
|
||||
fmt.Fprintln(os.Stderr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if string(pw1) != string(pw2) {
|
||||
return nil, errors.New("passwords do not match")
|
||||
}
|
||||
return pw1, nil
|
||||
}
|
144
vendor/github.com/sigstore/sigstore/pkg/cryptoutils/privatekey.go
generated
vendored
Normal file
144
vendor/github.com/sigstore/sigstore/pkg/cryptoutils/privatekey.go
generated
vendored
Normal file
@@ -0,0 +1,144 @@
|
||||
//
|
||||
// Copyright 2021 The Sigstore Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package cryptoutils
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/theupdateframework/go-tuf/encrypted"
|
||||
)
|
||||
|
||||
const (
|
||||
// PrivateKeyPEMType is the string "PRIVATE KEY" to be used during PEM encoding and decoding
|
||||
PrivateKeyPEMType PEMType = "PRIVATE KEY"
|
||||
encryptedCosignPrivateKeyPEMType PEMType = "ENCRYPTED COSIGN PRIVATE KEY"
|
||||
// EncryptedSigstorePrivateKeyPEMType is the string "ENCRYPTED SIGSTORE PRIVATE KEY" to be used during PEM encoding and decoding
|
||||
EncryptedSigstorePrivateKeyPEMType PEMType = "ENCRYPTED SIGSTORE PRIVATE KEY"
|
||||
)
|
||||
|
||||
func pemEncodeKeyPair(priv crypto.PrivateKey, pub crypto.PublicKey, pf PassFunc) (privPEM, pubPEM []byte, err error) {
|
||||
pubPEM, err = MarshalPublicKeyToPEM(pub)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
derBytes, err := MarshalPrivateKeyToDER(priv)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if pf == nil {
|
||||
return PEMEncode(PrivateKeyPEMType, derBytes), pubPEM, nil
|
||||
}
|
||||
password, err := pf(true)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if password == nil {
|
||||
return PEMEncode(PrivateKeyPEMType, derBytes), pubPEM, nil
|
||||
}
|
||||
if derBytes, err = encrypted.Encrypt(derBytes, password); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return PEMEncode(EncryptedSigstorePrivateKeyPEMType, derBytes), pubPEM, nil
|
||||
}
|
||||
|
||||
// GeneratePEMEncodedECDSAKeyPair generates an ECDSA keypair, optionally password encrypted using a provided PassFunc, and PEM encoded.
|
||||
func GeneratePEMEncodedECDSAKeyPair(curve elliptic.Curve, pf PassFunc) (privPEM, pubPEM []byte, err error) {
|
||||
priv, err := ecdsa.GenerateKey(curve, rand.Reader)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return pemEncodeKeyPair(priv, priv.Public(), pf)
|
||||
}
|
||||
|
||||
// GeneratePEMEncodedRSAKeyPair generates an RSA keypair, optionally password encrypted using a provided PassFunc, and PEM encoded.
|
||||
func GeneratePEMEncodedRSAKeyPair(keyLengthBits int, pf PassFunc) (privPEM, pubPEM []byte, err error) {
|
||||
priv, err := rsa.GenerateKey(rand.Reader, keyLengthBits)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return pemEncodeKeyPair(priv, priv.Public(), pf)
|
||||
}
|
||||
|
||||
// MarshalPrivateKeyToEncryptedDER marshals the private key and encrypts the DER-encoded value using the specified password function
|
||||
func MarshalPrivateKeyToEncryptedDER(priv crypto.PrivateKey, pf PassFunc) ([]byte, error) {
|
||||
derKey, err := MarshalPrivateKeyToDER(priv)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
password, err := pf(true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if password == nil {
|
||||
return nil, errors.New("password was nil")
|
||||
}
|
||||
return encrypted.Encrypt(derKey, password)
|
||||
}
|
||||
|
||||
// UnmarshalPEMToPrivateKey converts a PEM-encoded byte slice into a crypto.PrivateKey
|
||||
func UnmarshalPEMToPrivateKey(pemBytes []byte, pf PassFunc) (crypto.PrivateKey, error) {
|
||||
derBlock, _ := pem.Decode(pemBytes)
|
||||
if derBlock == nil {
|
||||
return nil, errors.New("PEM decoding failed")
|
||||
}
|
||||
switch derBlock.Type {
|
||||
case string(PrivateKeyPEMType):
|
||||
return x509.ParsePKCS8PrivateKey(derBlock.Bytes)
|
||||
case string(EncryptedSigstorePrivateKeyPEMType), string(encryptedCosignPrivateKeyPEMType):
|
||||
derBytes := derBlock.Bytes
|
||||
if pf != nil {
|
||||
password, err := pf(false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if password != nil {
|
||||
derBytes, err = encrypted.Decrypt(derBytes, password)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return x509.ParsePKCS8PrivateKey(derBytes)
|
||||
}
|
||||
return nil, fmt.Errorf("unknown PEM file type: %v", derBlock.Type)
|
||||
}
|
||||
|
||||
// MarshalPrivateKeyToDER converts a crypto.PrivateKey into a PKCS8 ASN.1 DER byte slice
|
||||
func MarshalPrivateKeyToDER(priv crypto.PrivateKey) ([]byte, error) {
|
||||
if priv == nil {
|
||||
return nil, errors.New("empty key")
|
||||
}
|
||||
return x509.MarshalPKCS8PrivateKey(priv)
|
||||
}
|
||||
|
||||
// MarshalPrivateKeyToPEM converts a crypto.PrivateKey into a PEM-encoded byte slice
|
||||
func MarshalPrivateKeyToPEM(priv crypto.PrivateKey) ([]byte, error) {
|
||||
derBytes, err := MarshalPrivateKeyToDER(priv)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return PEMEncode(PrivateKeyPEMType, derBytes), nil
|
||||
}
|
174
vendor/github.com/sigstore/sigstore/pkg/cryptoutils/publickey.go
generated
vendored
Normal file
174
vendor/github.com/sigstore/sigstore/pkg/cryptoutils/publickey.go
generated
vendored
Normal file
@@ -0,0 +1,174 @@
|
||||
//
|
||||
// Copyright 2021 The Sigstore Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package cryptoutils
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
"crypto/ed25519"
|
||||
"crypto/elliptic"
|
||||
"crypto/rsa"
|
||||
"crypto/sha1" // nolint:gosec
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/asn1"
|
||||
"encoding/hex"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/letsencrypt/boulder/goodkey"
|
||||
)
|
||||
|
||||
const (
|
||||
// PublicKeyPEMType is the string "PUBLIC KEY" to be used during PEM encoding and decoding
|
||||
PublicKeyPEMType PEMType = "PUBLIC KEY"
|
||||
)
|
||||
|
||||
// subjectPublicKeyInfo is used to construct a subject key ID.
|
||||
// https://tools.ietf.org/html/rfc5280#section-4.1.2.7
|
||||
type subjectPublicKeyInfo struct {
|
||||
Algorithm pkix.AlgorithmIdentifier
|
||||
SubjectPublicKey asn1.BitString
|
||||
}
|
||||
|
||||
// UnmarshalPEMToPublicKey converts a PEM-encoded byte slice into a crypto.PublicKey
|
||||
func UnmarshalPEMToPublicKey(pemBytes []byte) (crypto.PublicKey, error) {
|
||||
derBytes, _ := pem.Decode(pemBytes)
|
||||
if derBytes == nil {
|
||||
return nil, errors.New("PEM decoding failed")
|
||||
}
|
||||
return x509.ParsePKIXPublicKey(derBytes.Bytes)
|
||||
}
|
||||
|
||||
// MarshalPublicKeyToDER converts a crypto.PublicKey into a PKIX, ASN.1 DER byte slice
|
||||
func MarshalPublicKeyToDER(pub crypto.PublicKey) ([]byte, error) {
|
||||
if pub == nil {
|
||||
return nil, errors.New("empty key")
|
||||
}
|
||||
return x509.MarshalPKIXPublicKey(pub)
|
||||
}
|
||||
|
||||
// MarshalPublicKeyToPEM converts a crypto.PublicKey into a PEM-encoded byte slice
|
||||
func MarshalPublicKeyToPEM(pub crypto.PublicKey) ([]byte, error) {
|
||||
derBytes, err := MarshalPublicKeyToDER(pub)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return PEMEncode(PublicKeyPEMType, derBytes), nil
|
||||
}
|
||||
|
||||
// SKID generates a 160-bit SHA-1 hash of the value of the BIT STRING
|
||||
// subjectPublicKey (excluding the tag, length, and number of unused bits).
|
||||
// https://tools.ietf.org/html/rfc5280#section-4.2.1.2
|
||||
func SKID(pub crypto.PublicKey) ([]byte, error) {
|
||||
derPubBytes, err := x509.MarshalPKIXPublicKey(pub)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var spki subjectPublicKeyInfo
|
||||
if _, err := asn1.Unmarshal(derPubBytes, &spki); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
skid := sha1.Sum(spki.SubjectPublicKey.Bytes) // nolint:gosec
|
||||
return skid[:], nil
|
||||
}
|
||||
|
||||
// EqualKeys compares two public keys. Supports RSA, ECDSA and ED25519.
|
||||
// If not equal, the error message contains hex-encoded SHA1 hashes of the DER-encoded keys
|
||||
func EqualKeys(first, second crypto.PublicKey) error {
|
||||
switch pub := first.(type) {
|
||||
case *rsa.PublicKey:
|
||||
if !pub.Equal(second) {
|
||||
return fmt.Errorf(genErrMsg(first, second, "rsa"))
|
||||
}
|
||||
case *ecdsa.PublicKey:
|
||||
if !pub.Equal(second) {
|
||||
return fmt.Errorf(genErrMsg(first, second, "ecdsa"))
|
||||
}
|
||||
case ed25519.PublicKey:
|
||||
if !pub.Equal(second) {
|
||||
return fmt.Errorf(genErrMsg(first, second, "ed25519"))
|
||||
}
|
||||
default:
|
||||
return errors.New("unsupported key type")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// genErrMsg generates an error message for EqualKeys
|
||||
func genErrMsg(first, second crypto.PublicKey, keyType string) string {
|
||||
msg := fmt.Sprintf("%s public keys are not equal", keyType)
|
||||
// Calculate SKID to include in error message
|
||||
firstSKID, err := SKID(first)
|
||||
if err != nil {
|
||||
return msg
|
||||
}
|
||||
secondSKID, err := SKID(second)
|
||||
if err != nil {
|
||||
return msg
|
||||
}
|
||||
return fmt.Sprintf("%s (%s, %s)", msg, hex.EncodeToString(firstSKID), hex.EncodeToString(secondSKID))
|
||||
}
|
||||
|
||||
// ValidatePubKey validates the parameters of an RSA, ECDSA, or ED25519 public key.
|
||||
func ValidatePubKey(pub crypto.PublicKey) error {
|
||||
switch pk := pub.(type) {
|
||||
case *rsa.PublicKey:
|
||||
// goodkey policy enforces:
|
||||
// * Size of key: 2048 <= size <= 4096, size % 8 = 0
|
||||
// * Exponent E = 65537 (Default exponent for OpenSSL and Golang)
|
||||
// * Small primes check for modulus
|
||||
// * Weak keys generated by Infineon hardware (see https://crocs.fi.muni.cz/public/papers/rsa_ccs17)
|
||||
// * Key is easily factored with Fermat's factorization method
|
||||
p, err := goodkey.NewKeyPolicy(&goodkey.Config{FermatRounds: 100}, nil)
|
||||
if err != nil {
|
||||
// Should not occur, only chances to return errors are if fermat rounds
|
||||
// are <0 or when loading blocked/weak keys from disk (not used here)
|
||||
return errors.New("unable to initialize key policy")
|
||||
}
|
||||
// ctx is unused
|
||||
return p.GoodKey(context.Background(), pub)
|
||||
case *ecdsa.PublicKey:
|
||||
// Unable to use goodkey policy because P-521 curve is not supported
|
||||
return validateEcdsaKey(pk)
|
||||
case ed25519.PublicKey:
|
||||
return validateEd25519Key(pk)
|
||||
}
|
||||
return errors.New("unsupported public key type")
|
||||
}
|
||||
|
||||
// Enforce that the ECDSA key curve is one of:
|
||||
// * NIST P-256 (secp256r1, prime256v1)
|
||||
// * NIST P-384
|
||||
// * NIST P-521.
|
||||
// Other EC curves, like secp256k1, are not supported by Go.
|
||||
func validateEcdsaKey(pub *ecdsa.PublicKey) error {
|
||||
switch pub.Curve {
|
||||
case elliptic.P224():
|
||||
return fmt.Errorf("unsupported ec curve, expected NIST P-256, P-384, or P-521")
|
||||
case elliptic.P256(), elliptic.P384(), elliptic.P521():
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("unexpected ec curve")
|
||||
}
|
||||
}
|
||||
|
||||
// No validations currently, ED25519 supports only one key size.
|
||||
func validateEd25519Key(pub ed25519.PublicKey) error {
|
||||
return nil
|
||||
}
|
17
vendor/github.com/sigstore/sigstore/pkg/signature/doc.go
generated
vendored
Normal file
17
vendor/github.com/sigstore/sigstore/pkg/signature/doc.go
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
//
|
||||
// Copyright 2021 The Sigstore Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package signature contains types and utilities related to Sigstore signatures.
|
||||
package signature
|
244
vendor/github.com/sigstore/sigstore/pkg/signature/ecdsa.go
generated
vendored
Normal file
244
vendor/github.com/sigstore/sigstore/pkg/signature/ecdsa.go
generated
vendored
Normal file
@@ -0,0 +1,244 @@
|
||||
//
|
||||
// Copyright 2021 The Sigstore Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package signature
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/sigstore/sigstore/pkg/signature/options"
|
||||
)
|
||||
|
||||
// checked on LoadSigner, LoadVerifier and SignMessage
|
||||
var ecdsaSupportedHashFuncs = []crypto.Hash{
|
||||
crypto.SHA256,
|
||||
crypto.SHA512,
|
||||
crypto.SHA384,
|
||||
crypto.SHA224,
|
||||
}
|
||||
|
||||
// checked on VerifySignature. Supports SHA1 verification.
|
||||
var ecdsaSupportedVerifyHashFuncs = []crypto.Hash{
|
||||
crypto.SHA256,
|
||||
crypto.SHA512,
|
||||
crypto.SHA384,
|
||||
crypto.SHA224,
|
||||
crypto.SHA1,
|
||||
}
|
||||
|
||||
// ECDSASigner is a signature.Signer that uses an Elliptic Curve DSA algorithm
|
||||
type ECDSASigner struct {
|
||||
hashFunc crypto.Hash
|
||||
priv *ecdsa.PrivateKey
|
||||
}
|
||||
|
||||
// LoadECDSASigner calculates signatures using the specified private key and hash algorithm.
|
||||
//
|
||||
// hf must not be crypto.Hash(0).
|
||||
func LoadECDSASigner(priv *ecdsa.PrivateKey, hf crypto.Hash) (*ECDSASigner, error) {
|
||||
if priv == nil {
|
||||
return nil, errors.New("invalid ECDSA private key specified")
|
||||
}
|
||||
|
||||
if !isSupportedAlg(hf, ecdsaSupportedHashFuncs) {
|
||||
return nil, errors.New("invalid hash function specified")
|
||||
}
|
||||
|
||||
return &ECDSASigner{
|
||||
priv: priv,
|
||||
hashFunc: hf,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// SignMessage signs the provided message. If the message is provided,
|
||||
// this method will compute the digest according to the hash function specified
|
||||
// when the ECDSASigner was created.
|
||||
//
|
||||
// This function recognizes the following Options listed in order of preference:
|
||||
//
|
||||
// - WithRand()
|
||||
//
|
||||
// - WithDigest()
|
||||
//
|
||||
// - WithCryptoSignerOpts()
|
||||
//
|
||||
// All other options are ignored if specified.
|
||||
func (e ECDSASigner) SignMessage(message io.Reader, opts ...SignOption) ([]byte, error) {
|
||||
digest, _, err := ComputeDigestForSigning(message, e.hashFunc, ecdsaSupportedHashFuncs, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rand := selectRandFromOpts(opts...)
|
||||
|
||||
return ecdsa.SignASN1(rand, e.priv, digest)
|
||||
}
|
||||
|
||||
// Public returns the public key that can be used to verify signatures created by
|
||||
// this signer.
|
||||
func (e ECDSASigner) Public() crypto.PublicKey {
|
||||
if e.priv == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return e.priv.Public()
|
||||
}
|
||||
|
||||
// PublicKey returns the public key that can be used to verify signatures created by
|
||||
// this signer. As this value is held in memory, all options provided in arguments
|
||||
// to this method are ignored.
|
||||
func (e ECDSASigner) PublicKey(_ ...PublicKeyOption) (crypto.PublicKey, error) {
|
||||
return e.Public(), nil
|
||||
}
|
||||
|
||||
// Sign computes the signature for the specified digest. If a source of entropy is
|
||||
// given in rand, it will be used instead of the default value (rand.Reader from crypto/rand).
|
||||
//
|
||||
// If opts are specified, the hash function in opts.Hash should be the one used to compute
|
||||
// digest. If opts are not specified, the value provided when the signer was created will be used instead.
|
||||
func (e ECDSASigner) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) {
|
||||
ecdsaOpts := []SignOption{options.WithDigest(digest), options.WithRand(rand)}
|
||||
if opts != nil {
|
||||
ecdsaOpts = append(ecdsaOpts, options.WithCryptoSignerOpts(opts))
|
||||
}
|
||||
|
||||
return e.SignMessage(nil, ecdsaOpts...)
|
||||
}
|
||||
|
||||
// ECDSAVerifier is a signature.Verifier that uses an Elliptic Curve DSA algorithm
|
||||
type ECDSAVerifier struct {
|
||||
publicKey *ecdsa.PublicKey
|
||||
hashFunc crypto.Hash
|
||||
}
|
||||
|
||||
// LoadECDSAVerifier returns a Verifier that verifies signatures using the specified
|
||||
// ECDSA public key and hash algorithm.
|
||||
//
|
||||
// hf must not be crypto.Hash(0).
|
||||
func LoadECDSAVerifier(pub *ecdsa.PublicKey, hashFunc crypto.Hash) (*ECDSAVerifier, error) {
|
||||
if pub == nil {
|
||||
return nil, errors.New("invalid ECDSA public key specified")
|
||||
}
|
||||
|
||||
if !isSupportedAlg(hashFunc, ecdsaSupportedHashFuncs) {
|
||||
return nil, errors.New("invalid hash function specified")
|
||||
}
|
||||
|
||||
return &ECDSAVerifier{
|
||||
publicKey: pub,
|
||||
hashFunc: hashFunc,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// PublicKey returns the public key that is used to verify signatures by
|
||||
// this verifier. As this value is held in memory, all options provided in arguments
|
||||
// to this method are ignored.
|
||||
func (e ECDSAVerifier) PublicKey(_ ...PublicKeyOption) (crypto.PublicKey, error) {
|
||||
return e.publicKey, nil
|
||||
}
|
||||
|
||||
// VerifySignature verifies the signature for the given message. Unless provided
|
||||
// in an option, the digest of the message will be computed using the hash function specified
|
||||
// when the ECDSAVerifier was created.
|
||||
//
|
||||
// This function returns nil if the verification succeeded, and an error message otherwise.
|
||||
//
|
||||
// This function recognizes the following Options listed in order of preference:
|
||||
//
|
||||
// - WithDigest()
|
||||
//
|
||||
// All other options are ignored if specified.
|
||||
func (e ECDSAVerifier) VerifySignature(signature, message io.Reader, opts ...VerifyOption) error {
|
||||
digest, _, err := ComputeDigestForVerifying(message, e.hashFunc, ecdsaSupportedVerifyHashFuncs, opts...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if signature == nil {
|
||||
return errors.New("nil signature passed to VerifySignature")
|
||||
}
|
||||
|
||||
sigBytes, err := io.ReadAll(signature)
|
||||
if err != nil {
|
||||
return fmt.Errorf("reading signature: %w", err)
|
||||
}
|
||||
|
||||
if !ecdsa.VerifyASN1(e.publicKey, digest, sigBytes) {
|
||||
return errors.New("invalid signature when validating ASN.1 encoded signature")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ECDSASignerVerifier is a signature.SignerVerifier that uses an Elliptic Curve DSA algorithm
|
||||
type ECDSASignerVerifier struct {
|
||||
*ECDSASigner
|
||||
*ECDSAVerifier
|
||||
}
|
||||
|
||||
// LoadECDSASignerVerifier creates a combined signer and verifier. This is a convenience object
|
||||
// that simply wraps an instance of ECDSASigner and ECDSAVerifier.
|
||||
func LoadECDSASignerVerifier(priv *ecdsa.PrivateKey, hf crypto.Hash) (*ECDSASignerVerifier, error) {
|
||||
signer, err := LoadECDSASigner(priv, hf)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("initializing signer: %w", err)
|
||||
}
|
||||
verifier, err := LoadECDSAVerifier(&priv.PublicKey, hf)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("initializing verifier: %w", err)
|
||||
}
|
||||
|
||||
return &ECDSASignerVerifier{
|
||||
ECDSASigner: signer,
|
||||
ECDSAVerifier: verifier,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// NewDefaultECDSASignerVerifier creates a combined signer and verifier using ECDSA.
|
||||
//
|
||||
// This creates a new ECDSA key using the P-256 curve and uses the SHA256 hashing algorithm.
|
||||
func NewDefaultECDSASignerVerifier() (*ECDSASignerVerifier, *ecdsa.PrivateKey, error) {
|
||||
return NewECDSASignerVerifier(elliptic.P256(), rand.Reader, crypto.SHA256)
|
||||
}
|
||||
|
||||
// NewECDSASignerVerifier creates a combined signer and verifier using ECDSA.
|
||||
//
|
||||
// This creates a new ECDSA key using the specified elliptic curve, entropy source, and hashing function.
|
||||
func NewECDSASignerVerifier(curve elliptic.Curve, rand io.Reader, hashFunc crypto.Hash) (*ECDSASignerVerifier, *ecdsa.PrivateKey, error) {
|
||||
priv, err := ecdsa.GenerateKey(curve, rand)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
sv, err := LoadECDSASignerVerifier(priv, hashFunc)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return sv, priv, nil
|
||||
}
|
||||
|
||||
// PublicKey returns the public key that is used to verify signatures by
|
||||
// this verifier. As this value is held in memory, all options provided in arguments
|
||||
// to this method are ignored.
|
||||
func (e ECDSASignerVerifier) PublicKey(_ ...PublicKeyOption) (crypto.PublicKey, error) {
|
||||
return e.publicKey, nil
|
||||
}
|
197
vendor/github.com/sigstore/sigstore/pkg/signature/ed25519.go
generated
vendored
Normal file
197
vendor/github.com/sigstore/sigstore/pkg/signature/ed25519.go
generated
vendored
Normal file
@@ -0,0 +1,197 @@
|
||||
//
|
||||
// Copyright 2021 The Sigstore Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package signature
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto"
|
||||
"crypto/ed25519"
|
||||
"crypto/rand"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
var ed25519SupportedHashFuncs = []crypto.Hash{
|
||||
crypto.Hash(0),
|
||||
}
|
||||
|
||||
// ED25519Signer is a signature.Signer that uses the Ed25519 public-key signature system
|
||||
type ED25519Signer struct {
|
||||
priv ed25519.PrivateKey
|
||||
}
|
||||
|
||||
// LoadED25519Signer calculates signatures using the specified private key.
|
||||
func LoadED25519Signer(priv ed25519.PrivateKey) (*ED25519Signer, error) {
|
||||
if priv == nil {
|
||||
return nil, errors.New("invalid ED25519 private key specified")
|
||||
}
|
||||
|
||||
// check this to avoid panic and throw error gracefully
|
||||
if len(priv) != ed25519.PrivateKeySize {
|
||||
return nil, errors.New("invalid size for ED25519 key")
|
||||
}
|
||||
|
||||
return &ED25519Signer{
|
||||
priv: priv,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// SignMessage signs the provided message. Passing the WithDigest option is not
|
||||
// supported as ED25519 performs a two pass hash over the message during the
|
||||
// signing process.
|
||||
//
|
||||
// All options are ignored.
|
||||
func (e ED25519Signer) SignMessage(message io.Reader, _ ...SignOption) ([]byte, error) {
|
||||
messageBytes, _, err := ComputeDigestForSigning(message, crypto.Hash(0), ed25519SupportedHashFuncs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ed25519.Sign(e.priv, messageBytes), nil
|
||||
}
|
||||
|
||||
// Public returns the public key that can be used to verify signatures created by
|
||||
// this signer.
|
||||
func (e ED25519Signer) Public() crypto.PublicKey {
|
||||
if e.priv == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return e.priv.Public()
|
||||
}
|
||||
|
||||
// PublicKey returns the public key that can be used to verify signatures created by
|
||||
// this signer. As this value is held in memory, all options provided in arguments
|
||||
// to this method are ignored.
|
||||
func (e ED25519Signer) PublicKey(_ ...PublicKeyOption) (crypto.PublicKey, error) {
|
||||
return e.Public(), nil
|
||||
}
|
||||
|
||||
// Sign computes the signature for the specified message; the first and third arguments to this
|
||||
// function are ignored as they are not used by the ED25519 algorithm.
|
||||
func (e ED25519Signer) Sign(_ io.Reader, message []byte, _ crypto.SignerOpts) ([]byte, error) {
|
||||
if message == nil {
|
||||
return nil, errors.New("message must not be nil")
|
||||
}
|
||||
return e.SignMessage(bytes.NewReader(message))
|
||||
}
|
||||
|
||||
// ED25519Verifier is a signature.Verifier that uses the Ed25519 public-key signature system
|
||||
type ED25519Verifier struct {
|
||||
publicKey ed25519.PublicKey
|
||||
}
|
||||
|
||||
// LoadED25519Verifier returns a Verifier that verifies signatures using the specified ED25519 public key.
|
||||
func LoadED25519Verifier(pub ed25519.PublicKey) (*ED25519Verifier, error) {
|
||||
if pub == nil {
|
||||
return nil, errors.New("invalid ED25519 public key specified")
|
||||
}
|
||||
|
||||
return &ED25519Verifier{
|
||||
publicKey: pub,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// PublicKey returns the public key that is used to verify signatures by
|
||||
// this verifier. As this value is held in memory, all options provided in arguments
|
||||
// to this method are ignored.
|
||||
func (e *ED25519Verifier) PublicKey(_ ...PublicKeyOption) (crypto.PublicKey, error) {
|
||||
return e.publicKey, nil
|
||||
}
|
||||
|
||||
// VerifySignature verifies the signature for the given message.
|
||||
//
|
||||
// This function returns nil if the verification succeeded, and an error message otherwise.
|
||||
//
|
||||
// All options are ignored if specified.
|
||||
func (e *ED25519Verifier) VerifySignature(signature, message io.Reader, _ ...VerifyOption) error {
|
||||
messageBytes, _, err := ComputeDigestForVerifying(message, crypto.Hash(0), ed25519SupportedHashFuncs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if signature == nil {
|
||||
return errors.New("nil signature passed to VerifySignature")
|
||||
}
|
||||
|
||||
sigBytes, err := io.ReadAll(signature)
|
||||
if err != nil {
|
||||
return fmt.Errorf("reading signature: %w", err)
|
||||
}
|
||||
|
||||
if !ed25519.Verify(e.publicKey, messageBytes, sigBytes) {
|
||||
return errors.New("failed to verify signature")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ED25519SignerVerifier is a signature.SignerVerifier that uses the Ed25519 public-key signature system
|
||||
type ED25519SignerVerifier struct {
|
||||
*ED25519Signer
|
||||
*ED25519Verifier
|
||||
}
|
||||
|
||||
// LoadED25519SignerVerifier creates a combined signer and verifier. This is
|
||||
// a convenience object that simply wraps an instance of ED25519Signer and ED25519Verifier.
|
||||
func LoadED25519SignerVerifier(priv ed25519.PrivateKey) (*ED25519SignerVerifier, error) {
|
||||
signer, err := LoadED25519Signer(priv)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("initializing signer: %w", err)
|
||||
}
|
||||
pub, ok := priv.Public().(ed25519.PublicKey)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("given key is not ed25519.PublicKey: %w", err)
|
||||
}
|
||||
verifier, err := LoadED25519Verifier(pub)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("initializing verifier: %w", err)
|
||||
}
|
||||
|
||||
return &ED25519SignerVerifier{
|
||||
ED25519Signer: signer,
|
||||
ED25519Verifier: verifier,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// NewDefaultED25519SignerVerifier creates a combined signer and verifier using ED25519.
|
||||
// This creates a new ED25519 key using crypto/rand as an entropy source.
|
||||
func NewDefaultED25519SignerVerifier() (*ED25519SignerVerifier, ed25519.PrivateKey, error) {
|
||||
return NewED25519SignerVerifier(rand.Reader)
|
||||
}
|
||||
|
||||
// NewED25519SignerVerifier creates a combined signer and verifier using ED25519.
|
||||
// This creates a new ED25519 key using the specified entropy source.
|
||||
func NewED25519SignerVerifier(rand io.Reader) (*ED25519SignerVerifier, ed25519.PrivateKey, error) {
|
||||
_, priv, err := ed25519.GenerateKey(rand)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
sv, err := LoadED25519SignerVerifier(priv)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return sv, priv, nil
|
||||
}
|
||||
|
||||
// PublicKey returns the public key that is used to verify signatures by
|
||||
// this verifier. As this value is held in memory, all options provided in arguments
|
||||
// to this method are ignored.
|
||||
func (e ED25519SignerVerifier) PublicKey(_ ...PublicKeyOption) (crypto.PublicKey, error) {
|
||||
return e.publicKey, nil
|
||||
}
|
111
vendor/github.com/sigstore/sigstore/pkg/signature/message.go
generated
vendored
Normal file
111
vendor/github.com/sigstore/sigstore/pkg/signature/message.go
generated
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
//
|
||||
// Copyright 2021 The Sigstore Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package signature
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
crand "crypto/rand"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
func isSupportedAlg(alg crypto.Hash, supportedAlgs []crypto.Hash) bool {
|
||||
if supportedAlgs == nil {
|
||||
return true
|
||||
}
|
||||
for _, supportedAlg := range supportedAlgs {
|
||||
if alg == supportedAlg {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// ComputeDigestForSigning calculates the digest value for the specified message using a hash function selected by the following process:
|
||||
//
|
||||
// - if a digest value is already specified in a SignOption and the length of the digest matches that of the selected hash function, the
|
||||
// digest value will be returned without any further computation
|
||||
// - if a hash function is given using WithCryptoSignerOpts(opts) as a SignOption, it will be used (if it is in the supported list)
|
||||
// - otherwise defaultHashFunc will be used (if it is in the supported list)
|
||||
func ComputeDigestForSigning(rawMessage io.Reader, defaultHashFunc crypto.Hash, supportedHashFuncs []crypto.Hash, opts ...SignOption) (digest []byte, hashedWith crypto.Hash, err error) {
|
||||
var cryptoSignerOpts crypto.SignerOpts = defaultHashFunc
|
||||
for _, opt := range opts {
|
||||
opt.ApplyDigest(&digest)
|
||||
opt.ApplyCryptoSignerOpts(&cryptoSignerOpts)
|
||||
}
|
||||
hashedWith = cryptoSignerOpts.HashFunc()
|
||||
if !isSupportedAlg(hashedWith, supportedHashFuncs) {
|
||||
return nil, crypto.Hash(0), fmt.Errorf("unsupported hash algorithm: %q not in %v", hashedWith.String(), supportedHashFuncs)
|
||||
}
|
||||
if len(digest) > 0 {
|
||||
if hashedWith != crypto.Hash(0) && len(digest) != hashedWith.Size() {
|
||||
err = errors.New("unexpected length of digest for hash function specified")
|
||||
}
|
||||
return
|
||||
}
|
||||
digest, err = hashMessage(rawMessage, hashedWith)
|
||||
return
|
||||
}
|
||||
|
||||
// ComputeDigestForVerifying calculates the digest value for the specified message using a hash function selected by the following process:
|
||||
//
|
||||
// - if a digest value is already specified in a SignOption and the length of the digest matches that of the selected hash function, the
|
||||
// digest value will be returned without any further computation
|
||||
// - if a hash function is given using WithCryptoSignerOpts(opts) as a SignOption, it will be used (if it is in the supported list)
|
||||
// - otherwise defaultHashFunc will be used (if it is in the supported list)
|
||||
func ComputeDigestForVerifying(rawMessage io.Reader, defaultHashFunc crypto.Hash, supportedHashFuncs []crypto.Hash, opts ...VerifyOption) (digest []byte, hashedWith crypto.Hash, err error) {
|
||||
var cryptoSignerOpts crypto.SignerOpts = defaultHashFunc
|
||||
for _, opt := range opts {
|
||||
opt.ApplyDigest(&digest)
|
||||
opt.ApplyCryptoSignerOpts(&cryptoSignerOpts)
|
||||
}
|
||||
hashedWith = cryptoSignerOpts.HashFunc()
|
||||
if !isSupportedAlg(hashedWith, supportedHashFuncs) {
|
||||
return nil, crypto.Hash(0), fmt.Errorf("unsupported hash algorithm: %q not in %v", hashedWith.String(), supportedHashFuncs)
|
||||
}
|
||||
if len(digest) > 0 {
|
||||
if hashedWith != crypto.Hash(0) && len(digest) != hashedWith.Size() {
|
||||
err = errors.New("unexpected length of digest for hash function specified")
|
||||
}
|
||||
return
|
||||
}
|
||||
digest, err = hashMessage(rawMessage, hashedWith)
|
||||
return
|
||||
}
|
||||
|
||||
func hashMessage(rawMessage io.Reader, hashFunc crypto.Hash) ([]byte, error) {
|
||||
if rawMessage == nil {
|
||||
return nil, errors.New("message cannot be nil")
|
||||
}
|
||||
if hashFunc == crypto.Hash(0) {
|
||||
return io.ReadAll(rawMessage)
|
||||
}
|
||||
hasher := hashFunc.New()
|
||||
// avoids reading entire message into memory
|
||||
if _, err := io.Copy(hasher, rawMessage); err != nil {
|
||||
return nil, fmt.Errorf("hashing message: %w", err)
|
||||
}
|
||||
return hasher.Sum(nil), nil
|
||||
}
|
||||
|
||||
func selectRandFromOpts(opts ...SignOption) io.Reader {
|
||||
rand := crand.Reader
|
||||
for _, opt := range opts {
|
||||
opt.ApplyRand(&rand)
|
||||
}
|
||||
return rand
|
||||
}
|
57
vendor/github.com/sigstore/sigstore/pkg/signature/options.go
generated
vendored
Normal file
57
vendor/github.com/sigstore/sigstore/pkg/signature/options.go
generated
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
//
|
||||
// Copyright 2021 The Sigstore Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package signature
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto"
|
||||
"io"
|
||||
|
||||
"github.com/sigstore/sigstore/pkg/signature/options"
|
||||
)
|
||||
|
||||
// RPCOption specifies options to be used when performing RPC
|
||||
type RPCOption interface {
|
||||
ApplyContext(*context.Context)
|
||||
ApplyRemoteVerification(*bool)
|
||||
ApplyRPCAuthOpts(opts *options.RPCAuth)
|
||||
ApplyKeyVersion(keyVersion *string)
|
||||
}
|
||||
|
||||
// PublicKeyOption specifies options to be used when obtaining a public key
|
||||
type PublicKeyOption interface {
|
||||
RPCOption
|
||||
}
|
||||
|
||||
// MessageOption specifies options to be used when processing messages during signing or verification
|
||||
type MessageOption interface {
|
||||
ApplyDigest(*[]byte)
|
||||
ApplyCryptoSignerOpts(*crypto.SignerOpts)
|
||||
}
|
||||
|
||||
// SignOption specifies options to be used when signing a message
|
||||
type SignOption interface {
|
||||
RPCOption
|
||||
MessageOption
|
||||
ApplyRand(*io.Reader)
|
||||
ApplyKeyVersionUsed(**string)
|
||||
}
|
||||
|
||||
// VerifyOption specifies options to be used when verifying a signature
|
||||
type VerifyOption interface {
|
||||
RPCOption
|
||||
MessageOption
|
||||
}
|
36
vendor/github.com/sigstore/sigstore/pkg/signature/options/context.go
generated
vendored
Normal file
36
vendor/github.com/sigstore/sigstore/pkg/signature/options/context.go
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
//
|
||||
// Copyright 2021 The Sigstore Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package options
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
// RequestContext implements the functional option pattern for including a context during RPC
|
||||
type RequestContext struct {
|
||||
NoOpOptionImpl
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
// ApplyContext sets the specified context as the functional option
|
||||
func (r RequestContext) ApplyContext(ctx *context.Context) {
|
||||
*ctx = r.ctx
|
||||
}
|
||||
|
||||
// WithContext specifies that the given context should be used in RPC to external services
|
||||
func WithContext(ctx context.Context) RequestContext {
|
||||
return RequestContext{ctx: ctx}
|
||||
}
|
35
vendor/github.com/sigstore/sigstore/pkg/signature/options/digest.go
generated
vendored
Normal file
35
vendor/github.com/sigstore/sigstore/pkg/signature/options/digest.go
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
//
|
||||
// Copyright 2021 The Sigstore Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package options
|
||||
|
||||
// RequestDigest implements the functional option pattern for specifying a digest value
|
||||
type RequestDigest struct {
|
||||
NoOpOptionImpl
|
||||
digest []byte
|
||||
}
|
||||
|
||||
// ApplyDigest sets the specified digest value as the functional option
|
||||
func (r RequestDigest) ApplyDigest(digest *[]byte) {
|
||||
*digest = r.digest
|
||||
}
|
||||
|
||||
// WithDigest specifies that the given digest can be used by underlying signature implementations
|
||||
// WARNING: When verifying a digest with ECDSA, it is trivial to craft a valid signature
|
||||
// over a random message given a public key. Do not use this unles you understand the
|
||||
// implications and do not need to protect against malleability.
|
||||
func WithDigest(digest []byte) RequestDigest {
|
||||
return RequestDigest{digest: digest}
|
||||
}
|
50
vendor/github.com/sigstore/sigstore/pkg/signature/options/keyversion.go
generated
vendored
Normal file
50
vendor/github.com/sigstore/sigstore/pkg/signature/options/keyversion.go
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
//
|
||||
// Copyright 2022 The Sigstore Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package options
|
||||
|
||||
// RequestKeyVersion implements the functional option pattern for specifying the KMS key version during signing or verification
|
||||
type RequestKeyVersion struct {
|
||||
NoOpOptionImpl
|
||||
keyVersion string
|
||||
}
|
||||
|
||||
// ApplyKeyVersion sets the KMS's key version as a functional option
|
||||
func (r RequestKeyVersion) ApplyKeyVersion(keyVersion *string) {
|
||||
*keyVersion = r.keyVersion
|
||||
}
|
||||
|
||||
// WithKeyVersion specifies that a specific KMS key version be used during signing and verification operations;
|
||||
// a value of 0 will use the latest version of the key (default)
|
||||
func WithKeyVersion(keyVersion string) RequestKeyVersion {
|
||||
return RequestKeyVersion{keyVersion: keyVersion}
|
||||
}
|
||||
|
||||
// RequestKeyVersionUsed implements the functional option pattern for obtaining the KMS key version used during signing
|
||||
type RequestKeyVersionUsed struct {
|
||||
NoOpOptionImpl
|
||||
keyVersionUsed *string
|
||||
}
|
||||
|
||||
// ApplyKeyVersionUsed requests to store the KMS's key version that was used as a functional option
|
||||
func (r RequestKeyVersionUsed) ApplyKeyVersionUsed(keyVersionUsed **string) {
|
||||
*keyVersionUsed = r.keyVersionUsed
|
||||
}
|
||||
|
||||
// ReturnKeyVersionUsed specifies that the specific KMS key version that was used during signing should be stored
|
||||
// in the pointer provided
|
||||
func ReturnKeyVersionUsed(keyVersionUsed *string) RequestKeyVersionUsed {
|
||||
return RequestKeyVersionUsed{keyVersionUsed: keyVersionUsed}
|
||||
}
|
49
vendor/github.com/sigstore/sigstore/pkg/signature/options/noop.go
generated
vendored
Normal file
49
vendor/github.com/sigstore/sigstore/pkg/signature/options/noop.go
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
//
|
||||
// Copyright 2021 The Sigstore Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package options
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto"
|
||||
"io"
|
||||
)
|
||||
|
||||
// NoOpOptionImpl implements the RPCOption, SignOption, VerifyOption interfaces as no-ops.
|
||||
type NoOpOptionImpl struct{}
|
||||
|
||||
// ApplyContext is a no-op required to fully implement the requisite interfaces
|
||||
func (NoOpOptionImpl) ApplyContext(ctx *context.Context) {}
|
||||
|
||||
// ApplyCryptoSignerOpts is a no-op required to fully implement the requisite interfaces
|
||||
func (NoOpOptionImpl) ApplyCryptoSignerOpts(opts *crypto.SignerOpts) {}
|
||||
|
||||
// ApplyDigest is a no-op required to fully implement the requisite interfaces
|
||||
func (NoOpOptionImpl) ApplyDigest(digest *[]byte) {}
|
||||
|
||||
// ApplyRand is a no-op required to fully implement the requisite interfaces
|
||||
func (NoOpOptionImpl) ApplyRand(rand *io.Reader) {}
|
||||
|
||||
// ApplyRemoteVerification is a no-op required to fully implement the requisite interfaces
|
||||
func (NoOpOptionImpl) ApplyRemoteVerification(remoteVerification *bool) {}
|
||||
|
||||
// ApplyRPCAuthOpts is a no-op required to fully implement the requisite interfaces
|
||||
func (NoOpOptionImpl) ApplyRPCAuthOpts(opts *RPCAuth) {}
|
||||
|
||||
// ApplyKeyVersion is a no-op required to fully implement the requisite interfaces
|
||||
func (NoOpOptionImpl) ApplyKeyVersion(keyVersion *string) {}
|
||||
|
||||
// ApplyKeyVersionUsed is a no-op required to fully implement the requisite interfaces
|
||||
func (NoOpOptionImpl) ApplyKeyVersionUsed(keyVersion **string) {}
|
41
vendor/github.com/sigstore/sigstore/pkg/signature/options/rand.go
generated
vendored
Normal file
41
vendor/github.com/sigstore/sigstore/pkg/signature/options/rand.go
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
//
|
||||
// Copyright 2021 The Sigstore Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package options
|
||||
|
||||
import (
|
||||
crand "crypto/rand"
|
||||
"io"
|
||||
)
|
||||
|
||||
// RequestRand implements the functional option pattern for using a specific source of entropy
|
||||
type RequestRand struct {
|
||||
NoOpOptionImpl
|
||||
rand io.Reader
|
||||
}
|
||||
|
||||
// ApplyRand sets the specified source of entropy as the functional option
|
||||
func (r RequestRand) ApplyRand(rand *io.Reader) {
|
||||
*rand = r.rand
|
||||
}
|
||||
|
||||
// WithRand specifies that the given source of entropy should be used in signing operations
|
||||
func WithRand(rand io.Reader) RequestRand {
|
||||
r := rand
|
||||
if r == nil {
|
||||
r = crand.Reader
|
||||
}
|
||||
return RequestRand{rand: r}
|
||||
}
|
32
vendor/github.com/sigstore/sigstore/pkg/signature/options/remoteverification.go
generated
vendored
Normal file
32
vendor/github.com/sigstore/sigstore/pkg/signature/options/remoteverification.go
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
//
|
||||
// Copyright 2021 The Sigstore Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package options
|
||||
|
||||
// RequestRemoteVerification implements the functional option pattern for remotely verifiying signatures when possible
|
||||
type RequestRemoteVerification struct {
|
||||
NoOpOptionImpl
|
||||
remoteVerification bool
|
||||
}
|
||||
|
||||
// ApplyRemoteVerification sets remote verification as a functional option
|
||||
func (r RequestRemoteVerification) ApplyRemoteVerification(remoteVerification *bool) {
|
||||
*remoteVerification = r.remoteVerification
|
||||
}
|
||||
|
||||
// WithRemoteVerification specifies that the verification operation should be performed remotely (vs in the process of the caller)
|
||||
func WithRemoteVerification(remoteVerification bool) RequestRemoteVerification {
|
||||
return RequestRemoteVerification{remoteVerification: remoteVerification}
|
||||
}
|
58
vendor/github.com/sigstore/sigstore/pkg/signature/options/rpcauth.go
generated
vendored
Normal file
58
vendor/github.com/sigstore/sigstore/pkg/signature/options/rpcauth.go
generated
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
//
|
||||
// Copyright 2021 The Sigstore Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package options
|
||||
|
||||
// RPCAuthOpts includes authentication settings for RPC calls
|
||||
type RPCAuthOpts struct {
|
||||
NoOpOptionImpl
|
||||
opts RPCAuth
|
||||
}
|
||||
|
||||
// RPCAuth provides credentials for RPC calls, empty fields are ignored
|
||||
type RPCAuth struct {
|
||||
Address string // address is the remote server address, e.g. https://vault:8200
|
||||
Path string // path for the RPC, in vault this is the transit path which default to "transit"
|
||||
Token string // token used for RPC, in vault this is the VAULT_TOKEN value
|
||||
OIDC RPCAuthOIDC
|
||||
}
|
||||
|
||||
// RPCAuthOIDC is used to perform the RPC login using OIDC instead of a fixed token
|
||||
type RPCAuthOIDC struct {
|
||||
Path string // path defaults to "jwt" for vault
|
||||
Role string // role is required for jwt logins
|
||||
Token string // token is a jwt with vault
|
||||
}
|
||||
|
||||
// ApplyRPCAuthOpts sets the RPCAuth as a function option
|
||||
func (r RPCAuthOpts) ApplyRPCAuthOpts(opts *RPCAuth) {
|
||||
if r.opts.Address != "" {
|
||||
opts.Address = r.opts.Address
|
||||
}
|
||||
if r.opts.Path != "" {
|
||||
opts.Path = r.opts.Path
|
||||
}
|
||||
if r.opts.Token != "" {
|
||||
opts.Token = r.opts.Token
|
||||
}
|
||||
if r.opts.OIDC.Token != "" {
|
||||
opts.OIDC = r.opts.OIDC
|
||||
}
|
||||
}
|
||||
|
||||
// WithRPCAuthOpts specifies RPCAuth settings to be used with RPC logins
|
||||
func WithRPCAuthOpts(opts RPCAuth) RPCAuthOpts {
|
||||
return RPCAuthOpts{opts: opts}
|
||||
}
|
40
vendor/github.com/sigstore/sigstore/pkg/signature/options/signeropts.go
generated
vendored
Normal file
40
vendor/github.com/sigstore/sigstore/pkg/signature/options/signeropts.go
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
//
|
||||
// Copyright 2021 The Sigstore Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package options
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
)
|
||||
|
||||
// RequestCryptoSignerOpts implements the functional option pattern for supplying crypto.SignerOpts when signing or verifying
|
||||
type RequestCryptoSignerOpts struct {
|
||||
NoOpOptionImpl
|
||||
opts crypto.SignerOpts
|
||||
}
|
||||
|
||||
// ApplyCryptoSignerOpts sets crypto.SignerOpts as a functional option
|
||||
func (r RequestCryptoSignerOpts) ApplyCryptoSignerOpts(opts *crypto.SignerOpts) {
|
||||
*opts = r.opts
|
||||
}
|
||||
|
||||
// WithCryptoSignerOpts specifies that provided crypto.SignerOpts be used during signing and verification operations
|
||||
func WithCryptoSignerOpts(opts crypto.SignerOpts) RequestCryptoSignerOpts {
|
||||
var optsToUse crypto.SignerOpts = crypto.SHA256
|
||||
if opts != nil {
|
||||
optsToUse = opts
|
||||
}
|
||||
return RequestCryptoSignerOpts{opts: optsToUse}
|
||||
}
|
104
vendor/github.com/sigstore/sigstore/pkg/signature/payload/payload.go
generated
vendored
Normal file
104
vendor/github.com/sigstore/sigstore/pkg/signature/payload/payload.go
generated
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
//
|
||||
// Copyright 2021 The Sigstore Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package payload
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/google/go-containerregistry/pkg/name"
|
||||
)
|
||||
|
||||
// CosignSignatureType is the value of `critical.type` in a SimpleContainerImage payload.
|
||||
const CosignSignatureType = "cosign container image signature"
|
||||
|
||||
// SimpleContainerImage describes the structure of a basic container image signature payload, as defined at:
|
||||
// https://github.com/containers/image/blob/master/docs/containers-signature.5.md#json-data-format
|
||||
type SimpleContainerImage struct {
|
||||
Critical Critical `json:"critical"` // Critical data critical to correctly evaluating the validity of the signature
|
||||
Optional map[string]interface{} `json:"optional"` // Optional optional metadata about the image
|
||||
}
|
||||
|
||||
// Critical data critical to correctly evaluating the validity of a signature
|
||||
type Critical struct {
|
||||
Identity Identity `json:"identity"` // Identity claimed identity of the image
|
||||
Image Image `json:"image"` // Image identifies the container that the signature applies to
|
||||
Type string `json:"type"` // Type must be 'atomic container signature'
|
||||
}
|
||||
|
||||
// Identity is the claimed identity of the image
|
||||
type Identity struct {
|
||||
DockerReference string `json:"docker-reference"` // DockerReference is a reference used to refer to or download the image
|
||||
}
|
||||
|
||||
// Image identifies the container image that the signature applies to
|
||||
type Image struct {
|
||||
DockerManifestDigest string `json:"docker-manifest-digest"` // DockerManifestDigest the manifest digest of the signed container image
|
||||
}
|
||||
|
||||
// Cosign describes a container image signed using Cosign
|
||||
type Cosign struct {
|
||||
Image name.Digest
|
||||
Annotations map[string]interface{}
|
||||
}
|
||||
|
||||
// SimpleContainerImage returns information about a container image in the github.com/containers/image/signature format
|
||||
func (p Cosign) SimpleContainerImage() SimpleContainerImage {
|
||||
return SimpleContainerImage{
|
||||
Critical: Critical{
|
||||
Identity: Identity{
|
||||
DockerReference: p.Image.Repository.Name(),
|
||||
},
|
||||
Image: Image{
|
||||
DockerManifestDigest: p.Image.DigestStr(),
|
||||
},
|
||||
Type: CosignSignatureType,
|
||||
},
|
||||
Optional: p.Annotations,
|
||||
}
|
||||
}
|
||||
|
||||
// MarshalJSON marshals the container signature into a []byte of JSON data
|
||||
func (p Cosign) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(p.SimpleContainerImage())
|
||||
}
|
||||
|
||||
var _ json.Marshaler = Cosign{}
|
||||
|
||||
// UnmarshalJSON unmarshals []byte of JSON data into a container signature object
|
||||
func (p *Cosign) UnmarshalJSON(data []byte) error {
|
||||
if string(data) == "null" {
|
||||
// JSON "null" is a no-op by convention
|
||||
return nil
|
||||
}
|
||||
var simple SimpleContainerImage
|
||||
if err := json.Unmarshal(data, &simple); err != nil {
|
||||
return err
|
||||
}
|
||||
if simple.Critical.Type != CosignSignatureType {
|
||||
return fmt.Errorf("Cosign signature payload was of an unknown type: %q", simple.Critical.Type)
|
||||
}
|
||||
digestStr := simple.Critical.Identity.DockerReference + "@" + simple.Critical.Image.DockerManifestDigest
|
||||
digest, err := name.NewDigest(digestStr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not parse image digest string %q: %w", digestStr, err)
|
||||
}
|
||||
p.Image = digest
|
||||
p.Annotations = simple.Optional
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ json.Unmarshaler = (*Cosign)(nil)
|
25
vendor/github.com/sigstore/sigstore/pkg/signature/publickey.go
generated
vendored
Normal file
25
vendor/github.com/sigstore/sigstore/pkg/signature/publickey.go
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
//
|
||||
// Copyright 2021 The Sigstore Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package signature
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
)
|
||||
|
||||
// PublicKeyProvider returns a PublicKey associated with a digital signature
|
||||
type PublicKeyProvider interface {
|
||||
PublicKey(opts ...PublicKeyOption) (crypto.PublicKey, error)
|
||||
}
|
225
vendor/github.com/sigstore/sigstore/pkg/signature/rsapkcs1v15.go
generated
vendored
Normal file
225
vendor/github.com/sigstore/sigstore/pkg/signature/rsapkcs1v15.go
generated
vendored
Normal file
@@ -0,0 +1,225 @@
|
||||
//
|
||||
// Copyright 2021 The Sigstore Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package signature
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/sigstore/sigstore/pkg/signature/options"
|
||||
)
|
||||
|
||||
// RSAPKCS1v15Signer is a signature.Signer that uses the RSA PKCS1v15 algorithm
|
||||
type RSAPKCS1v15Signer struct {
|
||||
hashFunc crypto.Hash
|
||||
priv *rsa.PrivateKey
|
||||
}
|
||||
|
||||
// LoadRSAPKCS1v15Signer calculates signatures using the specified private key and hash algorithm.
|
||||
//
|
||||
// hf must be either SHA256, SHA388, or SHA512.
|
||||
func LoadRSAPKCS1v15Signer(priv *rsa.PrivateKey, hf crypto.Hash) (*RSAPKCS1v15Signer, error) {
|
||||
if priv == nil {
|
||||
return nil, errors.New("invalid RSA private key specified")
|
||||
}
|
||||
|
||||
if !isSupportedAlg(hf, rsaSupportedHashFuncs) {
|
||||
return nil, errors.New("invalid hash function specified")
|
||||
}
|
||||
|
||||
return &RSAPKCS1v15Signer{
|
||||
priv: priv,
|
||||
hashFunc: hf,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// SignMessage signs the provided message using PKCS1v15. If the message is provided,
|
||||
// this method will compute the digest according to the hash function specified
|
||||
// when the RSAPKCS1v15Signer was created.
|
||||
//
|
||||
// SignMessage recognizes the following Options listed in order of preference:
|
||||
//
|
||||
// - WithRand()
|
||||
//
|
||||
// - WithDigest()
|
||||
//
|
||||
// - WithCryptoSignerOpts()
|
||||
//
|
||||
// All other options are ignored if specified.
|
||||
func (r RSAPKCS1v15Signer) SignMessage(message io.Reader, opts ...SignOption) ([]byte, error) {
|
||||
digest, hf, err := ComputeDigestForSigning(message, r.hashFunc, rsaSupportedHashFuncs, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rand := selectRandFromOpts(opts...)
|
||||
|
||||
return rsa.SignPKCS1v15(rand, r.priv, hf, digest)
|
||||
}
|
||||
|
||||
// Public returns the public key that can be used to verify signatures created by
|
||||
// this signer.
|
||||
func (r RSAPKCS1v15Signer) Public() crypto.PublicKey {
|
||||
if r.priv == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return r.priv.Public()
|
||||
}
|
||||
|
||||
// PublicKey returns the public key that can be used to verify signatures created by
|
||||
// this signer. As this value is held in memory, all options provided in arguments
|
||||
// to this method are ignored.
|
||||
func (r RSAPKCS1v15Signer) PublicKey(_ ...PublicKeyOption) (crypto.PublicKey, error) {
|
||||
return r.Public(), nil
|
||||
}
|
||||
|
||||
// Sign computes the signature for the specified digest using PKCS1v15.
|
||||
//
|
||||
// If a source of entropy is given in rand, it will be used instead of the default value (rand.Reader
|
||||
// from crypto/rand).
|
||||
//
|
||||
// If opts are specified, they should specify the hash function used to compute digest. If opts are
|
||||
// not specified, this function assumes the hash function provided when the signer was created was
|
||||
// used to create the value specified in digest.
|
||||
func (r RSAPKCS1v15Signer) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) {
|
||||
rsaOpts := []SignOption{options.WithDigest(digest), options.WithRand(rand)}
|
||||
if opts != nil {
|
||||
rsaOpts = append(rsaOpts, options.WithCryptoSignerOpts(opts))
|
||||
}
|
||||
|
||||
return r.SignMessage(nil, rsaOpts...)
|
||||
}
|
||||
|
||||
// RSAPKCS1v15Verifier is a signature.Verifier that uses the RSA PKCS1v15 algorithm
|
||||
type RSAPKCS1v15Verifier struct {
|
||||
publicKey *rsa.PublicKey
|
||||
hashFunc crypto.Hash
|
||||
}
|
||||
|
||||
// LoadRSAPKCS1v15Verifier returns a Verifier that verifies signatures using the specified
|
||||
// RSA public key and hash algorithm.
|
||||
//
|
||||
// hf must be either SHA256, SHA388, or SHA512.
|
||||
func LoadRSAPKCS1v15Verifier(pub *rsa.PublicKey, hashFunc crypto.Hash) (*RSAPKCS1v15Verifier, error) {
|
||||
if pub == nil {
|
||||
return nil, errors.New("invalid RSA public key specified")
|
||||
}
|
||||
|
||||
if !isSupportedAlg(hashFunc, rsaSupportedHashFuncs) {
|
||||
return nil, errors.New("invalid hash function specified")
|
||||
}
|
||||
|
||||
return &RSAPKCS1v15Verifier{
|
||||
publicKey: pub,
|
||||
hashFunc: hashFunc,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// PublicKey returns the public key that is used to verify signatures by
|
||||
// this verifier. As this value is held in memory, all options provided in arguments
|
||||
// to this method are ignored.
|
||||
func (r RSAPKCS1v15Verifier) PublicKey(_ ...PublicKeyOption) (crypto.PublicKey, error) {
|
||||
return r.publicKey, nil
|
||||
}
|
||||
|
||||
// VerifySignature verifies the signature for the given message using PKCS1v15. Unless provided
|
||||
// in an option, the digest of the message will be computed using the hash function specified
|
||||
// when the RSAPKCS1v15Verifier was created.
|
||||
//
|
||||
// This function returns nil if the verification succeeded, and an error message otherwise.
|
||||
//
|
||||
// This function recognizes the following Options listed in order of preference:
|
||||
//
|
||||
// - WithDigest()
|
||||
//
|
||||
// - WithCryptoSignerOpts()
|
||||
//
|
||||
// All other options are ignored if specified.
|
||||
func (r RSAPKCS1v15Verifier) VerifySignature(signature, message io.Reader, opts ...VerifyOption) error {
|
||||
digest, hf, err := ComputeDigestForVerifying(message, r.hashFunc, rsaSupportedVerifyHashFuncs, opts...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if signature == nil {
|
||||
return errors.New("nil signature passed to VerifySignature")
|
||||
}
|
||||
|
||||
sigBytes, err := io.ReadAll(signature)
|
||||
if err != nil {
|
||||
return fmt.Errorf("reading signature: %w", err)
|
||||
}
|
||||
|
||||
return rsa.VerifyPKCS1v15(r.publicKey, hf, digest, sigBytes)
|
||||
}
|
||||
|
||||
// RSAPKCS1v15SignerVerifier is a signature.SignerVerifier that uses the RSA PKCS1v15 algorithm
|
||||
type RSAPKCS1v15SignerVerifier struct {
|
||||
*RSAPKCS1v15Signer
|
||||
*RSAPKCS1v15Verifier
|
||||
}
|
||||
|
||||
// LoadRSAPKCS1v15SignerVerifier creates a combined signer and verifier. This is a convenience object
|
||||
// that simply wraps an instance of RSAPKCS1v15Signer and RSAPKCS1v15Verifier.
|
||||
func LoadRSAPKCS1v15SignerVerifier(priv *rsa.PrivateKey, hf crypto.Hash) (*RSAPKCS1v15SignerVerifier, error) {
|
||||
signer, err := LoadRSAPKCS1v15Signer(priv, hf)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("initializing signer: %w", err)
|
||||
}
|
||||
verifier, err := LoadRSAPKCS1v15Verifier(&priv.PublicKey, hf)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("initializing verifier: %w", err)
|
||||
}
|
||||
|
||||
return &RSAPKCS1v15SignerVerifier{
|
||||
RSAPKCS1v15Signer: signer,
|
||||
RSAPKCS1v15Verifier: verifier,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// NewDefaultRSAPKCS1v15SignerVerifier creates a combined signer and verifier using RSA PKCS1v15.
|
||||
// This creates a new RSA key of 2048 bits and uses the SHA256 hashing algorithm.
|
||||
func NewDefaultRSAPKCS1v15SignerVerifier() (*RSAPKCS1v15SignerVerifier, *rsa.PrivateKey, error) {
|
||||
return NewRSAPKCS1v15SignerVerifier(rand.Reader, 2048, crypto.SHA256)
|
||||
}
|
||||
|
||||
// NewRSAPKCS1v15SignerVerifier creates a combined signer and verifier using RSA PKCS1v15.
|
||||
// This creates a new RSA key of the specified length of bits, entropy source, and hash function.
|
||||
func NewRSAPKCS1v15SignerVerifier(rand io.Reader, bits int, hashFunc crypto.Hash) (*RSAPKCS1v15SignerVerifier, *rsa.PrivateKey, error) {
|
||||
priv, err := rsa.GenerateKey(rand, bits)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
sv, err := LoadRSAPKCS1v15SignerVerifier(priv, hashFunc)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return sv, priv, nil
|
||||
}
|
||||
|
||||
// PublicKey returns the public key that is used to verify signatures by
|
||||
// this verifier. As this value is held in memory, all options provided in arguments
|
||||
// to this method are ignored.
|
||||
func (r RSAPKCS1v15SignerVerifier) PublicKey(_ ...PublicKeyOption) (crypto.PublicKey, error) {
|
||||
return r.publicKey, nil
|
||||
}
|
260
vendor/github.com/sigstore/sigstore/pkg/signature/rsapss.go
generated
vendored
Normal file
260
vendor/github.com/sigstore/sigstore/pkg/signature/rsapss.go
generated
vendored
Normal file
@@ -0,0 +1,260 @@
|
||||
//
|
||||
// Copyright 2021 The Sigstore Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package signature
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/sigstore/sigstore/pkg/signature/options"
|
||||
)
|
||||
|
||||
// checked on LoadSigner, LoadVerifier, and SignMessage
|
||||
var rsaSupportedHashFuncs = []crypto.Hash{
|
||||
crypto.SHA256,
|
||||
crypto.SHA384,
|
||||
crypto.SHA512,
|
||||
}
|
||||
|
||||
// checked on VerifySignature. Supports SHA1 verification.
|
||||
var rsaSupportedVerifyHashFuncs = []crypto.Hash{
|
||||
crypto.SHA1,
|
||||
crypto.SHA256,
|
||||
crypto.SHA384,
|
||||
crypto.SHA512,
|
||||
}
|
||||
|
||||
// RSAPSSSigner is a signature.Signer that uses the RSA PSS algorithm
|
||||
type RSAPSSSigner struct {
|
||||
hashFunc crypto.Hash
|
||||
priv *rsa.PrivateKey
|
||||
pssOpts *rsa.PSSOptions
|
||||
}
|
||||
|
||||
// LoadRSAPSSSigner calculates signatures using the specified private key and hash algorithm.
|
||||
//
|
||||
// If opts are specified, then they will be stored and used as a default if not overridden
|
||||
// by the value passed to Sign().
|
||||
//
|
||||
// hf must be either SHA256, SHA388, or SHA512. opts.Hash is ignored.
|
||||
func LoadRSAPSSSigner(priv *rsa.PrivateKey, hf crypto.Hash, opts *rsa.PSSOptions) (*RSAPSSSigner, error) {
|
||||
if priv == nil {
|
||||
return nil, errors.New("invalid RSA private key specified")
|
||||
}
|
||||
|
||||
if !isSupportedAlg(hf, rsaSupportedHashFuncs) {
|
||||
return nil, errors.New("invalid hash function specified")
|
||||
}
|
||||
|
||||
return &RSAPSSSigner{
|
||||
priv: priv,
|
||||
pssOpts: opts,
|
||||
hashFunc: hf,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// SignMessage signs the provided message using PSS. If the message is provided,
|
||||
// this method will compute the digest according to the hash function specified
|
||||
// when the RSAPSSSigner was created.
|
||||
//
|
||||
// This function recognizes the following Options listed in order of preference:
|
||||
//
|
||||
// - WithRand()
|
||||
//
|
||||
// - WithDigest()
|
||||
//
|
||||
// - WithCryptoSignerOpts()
|
||||
//
|
||||
// All other options are ignored if specified.
|
||||
func (r RSAPSSSigner) SignMessage(message io.Reader, opts ...SignOption) ([]byte, error) {
|
||||
digest, hf, err := ComputeDigestForSigning(message, r.hashFunc, rsaSupportedHashFuncs, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rand := selectRandFromOpts(opts...)
|
||||
pssOpts := r.pssOpts
|
||||
if pssOpts == nil {
|
||||
pssOpts = &rsa.PSSOptions{
|
||||
SaltLength: rsa.PSSSaltLengthAuto,
|
||||
}
|
||||
}
|
||||
pssOpts.Hash = hf
|
||||
|
||||
return rsa.SignPSS(rand, r.priv, hf, digest, pssOpts)
|
||||
}
|
||||
|
||||
// Public returns the public key that can be used to verify signatures created by
|
||||
// this signer.
|
||||
func (r RSAPSSSigner) Public() crypto.PublicKey {
|
||||
if r.priv == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return r.priv.Public()
|
||||
}
|
||||
|
||||
// PublicKey returns the public key that can be used to verify signatures created by
|
||||
// this signer. As this value is held in memory, all options provided in arguments
|
||||
// to this method are ignored.
|
||||
func (r RSAPSSSigner) PublicKey(_ ...PublicKeyOption) (crypto.PublicKey, error) {
|
||||
return r.Public(), nil
|
||||
}
|
||||
|
||||
// Sign computes the signature for the specified digest using PSS.
|
||||
//
|
||||
// If a source of entropy is given in rand, it will be used instead of the default value (rand.Reader
|
||||
// from crypto/rand).
|
||||
//
|
||||
// If opts are specified, they must be *rsa.PSSOptions. If opts are not specified, the hash function
|
||||
// provided when the signer was created will be assumed.
|
||||
func (r RSAPSSSigner) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) {
|
||||
rsaOpts := []SignOption{options.WithDigest(digest), options.WithRand(rand)}
|
||||
if opts != nil {
|
||||
rsaOpts = append(rsaOpts, options.WithCryptoSignerOpts(opts))
|
||||
}
|
||||
|
||||
return r.SignMessage(nil, rsaOpts...)
|
||||
}
|
||||
|
||||
// RSAPSSVerifier is a signature.Verifier that uses the RSA PSS algorithm
|
||||
type RSAPSSVerifier struct {
|
||||
publicKey *rsa.PublicKey
|
||||
hashFunc crypto.Hash
|
||||
pssOpts *rsa.PSSOptions
|
||||
}
|
||||
|
||||
// LoadRSAPSSVerifier verifies signatures using the specified public key and hash algorithm.
|
||||
//
|
||||
// hf must be either SHA256, SHA388, or SHA512. opts.Hash is ignored.
|
||||
func LoadRSAPSSVerifier(pub *rsa.PublicKey, hashFunc crypto.Hash, opts *rsa.PSSOptions) (*RSAPSSVerifier, error) {
|
||||
if pub == nil {
|
||||
return nil, errors.New("invalid RSA public key specified")
|
||||
}
|
||||
|
||||
if !isSupportedAlg(hashFunc, rsaSupportedHashFuncs) {
|
||||
return nil, errors.New("invalid hash function specified")
|
||||
}
|
||||
|
||||
return &RSAPSSVerifier{
|
||||
publicKey: pub,
|
||||
hashFunc: hashFunc,
|
||||
pssOpts: opts,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// PublicKey returns the public key that is used to verify signatures by
|
||||
// this verifier. As this value is held in memory, all options provided in arguments
|
||||
// to this method are ignored.
|
||||
func (r RSAPSSVerifier) PublicKey(_ ...PublicKeyOption) (crypto.PublicKey, error) {
|
||||
return r.publicKey, nil
|
||||
}
|
||||
|
||||
// VerifySignature verifies the signature for the given message using PSS. Unless provided
|
||||
// in an option, the digest of the message will be computed using the hash function specified
|
||||
// when the RSAPSSVerifier was created.
|
||||
//
|
||||
// This function returns nil if the verification succeeded, and an error message otherwise.
|
||||
//
|
||||
// This function recognizes the following Options listed in order of preference:
|
||||
//
|
||||
// - WithDigest()
|
||||
//
|
||||
// - WithCryptoSignerOpts()
|
||||
//
|
||||
// All other options are ignored if specified.
|
||||
func (r RSAPSSVerifier) VerifySignature(signature, message io.Reader, opts ...VerifyOption) error {
|
||||
digest, hf, err := ComputeDigestForVerifying(message, r.hashFunc, rsaSupportedVerifyHashFuncs, opts...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if signature == nil {
|
||||
return errors.New("nil signature passed to VerifySignature")
|
||||
}
|
||||
|
||||
sigBytes, err := io.ReadAll(signature)
|
||||
if err != nil {
|
||||
return fmt.Errorf("reading signature: %w", err)
|
||||
}
|
||||
|
||||
// rsa.VerifyPSS ignores pssOpts.Hash, so we don't set it
|
||||
pssOpts := r.pssOpts
|
||||
if pssOpts == nil {
|
||||
pssOpts = &rsa.PSSOptions{
|
||||
SaltLength: rsa.PSSSaltLengthAuto,
|
||||
}
|
||||
}
|
||||
|
||||
return rsa.VerifyPSS(r.publicKey, hf, digest, sigBytes, pssOpts)
|
||||
}
|
||||
|
||||
// RSAPSSSignerVerifier is a signature.SignerVerifier that uses the RSA PSS algorithm
|
||||
type RSAPSSSignerVerifier struct {
|
||||
*RSAPSSSigner
|
||||
*RSAPSSVerifier
|
||||
}
|
||||
|
||||
// LoadRSAPSSSignerVerifier creates a combined signer and verifier using RSA PSS. This is
|
||||
// a convenience object that simply wraps an instance of RSAPSSSigner and RSAPSSVerifier.
|
||||
func LoadRSAPSSSignerVerifier(priv *rsa.PrivateKey, hf crypto.Hash, opts *rsa.PSSOptions) (*RSAPSSSignerVerifier, error) {
|
||||
signer, err := LoadRSAPSSSigner(priv, hf, opts)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("initializing signer: %w", err)
|
||||
}
|
||||
verifier, err := LoadRSAPSSVerifier(&priv.PublicKey, hf, opts)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("initializing verifier: %w", err)
|
||||
}
|
||||
|
||||
return &RSAPSSSignerVerifier{
|
||||
RSAPSSSigner: signer,
|
||||
RSAPSSVerifier: verifier,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// NewDefaultRSAPSSSignerVerifier creates a combined signer and verifier using RSA PSS.
|
||||
// This creates a new RSA key of 2048 bits and uses the SHA256 hashing algorithm.
|
||||
func NewDefaultRSAPSSSignerVerifier() (*RSAPSSSignerVerifier, *rsa.PrivateKey, error) {
|
||||
return NewRSAPSSSignerVerifier(rand.Reader, 2048, crypto.SHA256)
|
||||
}
|
||||
|
||||
// NewRSAPSSSignerVerifier creates a combined signer and verifier using RSA PSS.
|
||||
// This creates a new RSA key of the specified length of bits, entropy source, and hash function.
|
||||
func NewRSAPSSSignerVerifier(rand io.Reader, bits int, hashFunc crypto.Hash) (*RSAPSSSignerVerifier, *rsa.PrivateKey, error) {
|
||||
priv, err := rsa.GenerateKey(rand, bits)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
sv, err := LoadRSAPSSSignerVerifier(priv, hashFunc, &rsa.PSSOptions{Hash: hashFunc})
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return sv, priv, nil
|
||||
}
|
||||
|
||||
// PublicKey returns the public key that is used to verify signatures by
|
||||
// this verifier. As this value is held in memory, all options provided in arguments
|
||||
// to this method are ignored.
|
||||
func (r RSAPSSSignerVerifier) PublicKey(_ ...PublicKeyOption) (crypto.PublicKey, error) {
|
||||
return r.publicKey, nil
|
||||
}
|
89
vendor/github.com/sigstore/sigstore/pkg/signature/signer.go
generated
vendored
Normal file
89
vendor/github.com/sigstore/sigstore/pkg/signature/signer.go
generated
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
//
|
||||
// Copyright 2021 The Sigstore Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package signature
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
"crypto/ed25519"
|
||||
"crypto/rsa"
|
||||
"errors"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
|
||||
// these ensure we have the implementations loaded
|
||||
_ "crypto/sha256"
|
||||
_ "crypto/sha512"
|
||||
|
||||
"github.com/sigstore/sigstore/pkg/cryptoutils"
|
||||
|
||||
// these ensure we have the implementations loaded
|
||||
_ "golang.org/x/crypto/sha3"
|
||||
)
|
||||
|
||||
// Signer creates digital signatures over a message using a specified key pair
|
||||
type Signer interface {
|
||||
PublicKeyProvider
|
||||
SignMessage(message io.Reader, opts ...SignOption) ([]byte, error)
|
||||
}
|
||||
|
||||
// SignerOpts implements crypto.SignerOpts but also allows callers to specify
|
||||
// additional options that may be utilized in signing the digest provided.
|
||||
type SignerOpts struct {
|
||||
Hash crypto.Hash
|
||||
Opts []SignOption
|
||||
}
|
||||
|
||||
// HashFunc returns the hash function for this object
|
||||
func (s SignerOpts) HashFunc() crypto.Hash {
|
||||
return s.Hash
|
||||
}
|
||||
|
||||
// LoadSigner returns a signature.Signer based on the algorithm of the private key
|
||||
// provided.
|
||||
//
|
||||
// If privateKey is an RSA key, a RSAPKCS1v15Signer will be returned. If a
|
||||
// RSAPSSSigner is desired instead, use the LoadRSAPSSSigner() method directly.
|
||||
func LoadSigner(privateKey crypto.PrivateKey, hashFunc crypto.Hash) (Signer, error) {
|
||||
switch pk := privateKey.(type) {
|
||||
case *rsa.PrivateKey:
|
||||
return LoadRSAPKCS1v15Signer(pk, hashFunc)
|
||||
case *ecdsa.PrivateKey:
|
||||
return LoadECDSASigner(pk, hashFunc)
|
||||
case ed25519.PrivateKey:
|
||||
return LoadED25519Signer(pk)
|
||||
}
|
||||
return nil, errors.New("unsupported public key type")
|
||||
}
|
||||
|
||||
// LoadSignerFromPEMFile returns a signature.Signer based on the algorithm of the private key
|
||||
// in the file. The Signer will use the hash function specified when computing digests.
|
||||
//
|
||||
// If key is an RSA key, a RSAPKCS1v15Signer will be returned. If a
|
||||
// RSAPSSSigner is desired instead, use the LoadRSAPSSSigner() and
|
||||
// cryptoutils.UnmarshalPEMToPrivateKey() methods directly.
|
||||
func LoadSignerFromPEMFile(path string, hashFunc crypto.Hash, pf cryptoutils.PassFunc) (Signer, error) {
|
||||
fileBytes, err := ioutil.ReadFile(filepath.Clean(path))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
priv, err := cryptoutils.UnmarshalPEMToPrivateKey(fileBytes, pf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return LoadSigner(priv, hashFunc)
|
||||
}
|
69
vendor/github.com/sigstore/sigstore/pkg/signature/signerverifier.go
generated
vendored
Normal file
69
vendor/github.com/sigstore/sigstore/pkg/signature/signerverifier.go
generated
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
//
|
||||
// Copyright 2021 The Sigstore Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package signature
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
"crypto/ed25519"
|
||||
"crypto/rsa"
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/sigstore/sigstore/pkg/cryptoutils"
|
||||
)
|
||||
|
||||
// SignerVerifier creates and verifies digital signatures over a message using a specified key pair
|
||||
type SignerVerifier interface {
|
||||
Signer
|
||||
Verifier
|
||||
}
|
||||
|
||||
// LoadSignerVerifier returns a signature.SignerVerifier based on the algorithm of the private key
|
||||
// provided.
|
||||
//
|
||||
// If privateKey is an RSA key, a RSAPKCS1v15SignerVerifier will be returned. If a
|
||||
// RSAPSSSignerVerifier is desired instead, use the LoadRSAPSSSignerVerifier() method directly.
|
||||
func LoadSignerVerifier(privateKey crypto.PrivateKey, hashFunc crypto.Hash) (SignerVerifier, error) {
|
||||
switch pk := privateKey.(type) {
|
||||
case *rsa.PrivateKey:
|
||||
return LoadRSAPKCS1v15SignerVerifier(pk, hashFunc)
|
||||
case *ecdsa.PrivateKey:
|
||||
return LoadECDSASignerVerifier(pk, hashFunc)
|
||||
case ed25519.PrivateKey:
|
||||
return LoadED25519SignerVerifier(pk)
|
||||
}
|
||||
return nil, errors.New("unsupported public key type")
|
||||
}
|
||||
|
||||
// LoadSignerVerifierFromPEMFile returns a signature.SignerVerifier based on the algorithm of the private key
|
||||
// in the file. The SignerVerifier will use the hash function specified when computing digests.
|
||||
//
|
||||
// If publicKey is an RSA key, a RSAPKCS1v15SignerVerifier will be returned. If a
|
||||
// RSAPSSSignerVerifier is desired instead, use the LoadRSAPSSSignerVerifier() and
|
||||
// cryptoutils.UnmarshalPEMToPrivateKey() methods directly.
|
||||
func LoadSignerVerifierFromPEMFile(path string, hashFunc crypto.Hash, pf cryptoutils.PassFunc) (SignerVerifier, error) {
|
||||
fileBytes, err := ioutil.ReadFile(filepath.Clean(path))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
priv, err := cryptoutils.UnmarshalPEMToPrivateKey(fileBytes, pf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return LoadSignerVerifier(priv, hashFunc)
|
||||
}
|
55
vendor/github.com/sigstore/sigstore/pkg/signature/util.go
generated
vendored
Normal file
55
vendor/github.com/sigstore/sigstore/pkg/signature/util.go
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
//
|
||||
// Copyright 2021 The Sigstore Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package signature
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/google/go-containerregistry/pkg/name"
|
||||
|
||||
sigpayload "github.com/sigstore/sigstore/pkg/signature/payload"
|
||||
)
|
||||
|
||||
// SignImage signs a container manifest using the specified signer object
|
||||
func SignImage(signer SignerVerifier, image name.Digest, optionalAnnotations map[string]interface{}) (payload, signature []byte, err error) {
|
||||
imgPayload := sigpayload.Cosign{
|
||||
Image: image,
|
||||
Annotations: optionalAnnotations,
|
||||
}
|
||||
payload, err = json.Marshal(imgPayload)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("failed to marshal payload to JSON: %w", err)
|
||||
}
|
||||
signature, err = signer.SignMessage(bytes.NewReader(payload))
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("failed to sign payload: %w", err)
|
||||
}
|
||||
return payload, signature, nil
|
||||
}
|
||||
|
||||
// VerifyImageSignature verifies a signature over a container manifest
|
||||
func VerifyImageSignature(signer SignerVerifier, payload, signature []byte) (image name.Digest, annotations map[string]interface{}, err error) {
|
||||
if err := signer.VerifySignature(bytes.NewReader(signature), bytes.NewReader(payload)); err != nil {
|
||||
return name.Digest{}, nil, fmt.Errorf("signature verification failed: %w", err)
|
||||
}
|
||||
var imgPayload sigpayload.Cosign
|
||||
if err := json.Unmarshal(payload, &imgPayload); err != nil {
|
||||
return name.Digest{}, nil, fmt.Errorf("could not deserialize image payload: %w", err)
|
||||
}
|
||||
return imgPayload.Image, imgPayload.Annotations, nil
|
||||
}
|
100
vendor/github.com/sigstore/sigstore/pkg/signature/verifier.go
generated
vendored
Normal file
100
vendor/github.com/sigstore/sigstore/pkg/signature/verifier.go
generated
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
//
|
||||
// Copyright 2021 The Sigstore Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package signature
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
"crypto/ed25519"
|
||||
"crypto/rsa"
|
||||
"errors"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/sigstore/sigstore/pkg/cryptoutils"
|
||||
)
|
||||
|
||||
// Verifier verifies the digital signature using a specified public key
|
||||
type Verifier interface {
|
||||
PublicKeyProvider
|
||||
VerifySignature(signature, message io.Reader, opts ...VerifyOption) error
|
||||
}
|
||||
|
||||
// LoadVerifier returns a signature.Verifier based on the algorithm of the public key
|
||||
// provided that will use the hash function specified when computing digests.
|
||||
//
|
||||
// If publicKey is an RSA key, a RSAPKCS1v15Verifier will be returned. If a
|
||||
// RSAPSSVerifier is desired instead, use the LoadRSAPSSVerifier() method directly.
|
||||
func LoadVerifier(publicKey crypto.PublicKey, hashFunc crypto.Hash) (Verifier, error) {
|
||||
switch pk := publicKey.(type) {
|
||||
case *rsa.PublicKey:
|
||||
return LoadRSAPKCS1v15Verifier(pk, hashFunc)
|
||||
case *ecdsa.PublicKey:
|
||||
return LoadECDSAVerifier(pk, hashFunc)
|
||||
case ed25519.PublicKey:
|
||||
return LoadED25519Verifier(pk)
|
||||
}
|
||||
return nil, errors.New("unsupported public key type")
|
||||
}
|
||||
|
||||
// LoadUnsafeVerifier returns a signature.Verifier based on the algorithm of the public key
|
||||
// provided that will use SHA1 when computing digests for RSA and ECDSA signatures.
|
||||
//
|
||||
// If publicKey is an RSA key, a RSAPKCS1v15Verifier will be returned. If a
|
||||
// RSAPSSVerifier is desired instead, use the LoadRSAPSSVerifier() method directly.
|
||||
func LoadUnsafeVerifier(publicKey crypto.PublicKey) (Verifier, error) {
|
||||
switch pk := publicKey.(type) {
|
||||
case *rsa.PublicKey:
|
||||
if pk == nil {
|
||||
return nil, errors.New("invalid RSA public key specified")
|
||||
}
|
||||
return &RSAPKCS1v15Verifier{
|
||||
publicKey: pk,
|
||||
hashFunc: crypto.SHA1,
|
||||
}, nil
|
||||
case *ecdsa.PublicKey:
|
||||
if pk == nil {
|
||||
return nil, errors.New("invalid ECDSA public key specified")
|
||||
}
|
||||
return &ECDSAVerifier{
|
||||
publicKey: pk,
|
||||
hashFunc: crypto.SHA1,
|
||||
}, nil
|
||||
case ed25519.PublicKey:
|
||||
return LoadED25519Verifier(pk)
|
||||
}
|
||||
return nil, errors.New("unsupported public key type")
|
||||
}
|
||||
|
||||
// LoadVerifierFromPEMFile returns a signature.Verifier based on the contents of a
|
||||
// file located at path. The Verifier wil use the hash function specified when computing digests.
|
||||
//
|
||||
// If the publickey is an RSA key, a RSAPKCS1v15Verifier will be returned. If a
|
||||
// RSAPSSVerifier is desired instead, use the LoadRSAPSSVerifier() and cryptoutils.UnmarshalPEMToPublicKey() methods directly.
|
||||
func LoadVerifierFromPEMFile(path string, hashFunc crypto.Hash) (Verifier, error) {
|
||||
fileBytes, err := ioutil.ReadFile(filepath.Clean(path))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pubKey, err := cryptoutils.UnmarshalPEMToPublicKey(fileBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return LoadVerifier(pubKey, hashFunc)
|
||||
}
|
Reference in New Issue
Block a user