feat: kubesphere 4.0 (#6115)
* feat: kubesphere 4.0 Signed-off-by: ci-bot <ci-bot@kubesphere.io> * feat: kubesphere 4.0 Signed-off-by: ci-bot <ci-bot@kubesphere.io> --------- Signed-off-by: ci-bot <ci-bot@kubesphere.io> Co-authored-by: ks-ci-bot <ks-ci-bot@example.com> Co-authored-by: joyceliu <joyceliu@yunify.com>
This commit is contained in:
committed by
GitHub
parent
b5015ec7b9
commit
447a51f08b
288
vendor/github.com/open-policy-agent/opa/topdown/crypto.go
generated
vendored
288
vendor/github.com/open-policy-agent/opa/topdown/crypto.go
generated
vendored
@@ -6,11 +6,13 @@ package topdown
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto"
|
||||
"crypto/hmac"
|
||||
"crypto/md5"
|
||||
"crypto/sha1"
|
||||
"crypto/sha256"
|
||||
"crypto/sha512"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
@@ -20,8 +22,9 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/open-policy-agent/opa/ast"
|
||||
"github.com/open-policy-agent/opa/internal/jwx/jwk"
|
||||
|
||||
"github.com/open-policy-agent/opa/ast"
|
||||
"github.com/open-policy-agent/opa/topdown/builtins"
|
||||
"github.com/open-policy-agent/opa/util"
|
||||
)
|
||||
@@ -38,7 +41,8 @@ const (
|
||||
blockTypeRSAPrivateKey = "RSA PRIVATE KEY"
|
||||
// blockTypeRSAPrivateKey indicates this PEM block contains a RSA private key.
|
||||
// Exported for tests.
|
||||
blockTypePrivateKey = "PRIVATE KEY"
|
||||
blockTypePrivateKey = "PRIVATE KEY"
|
||||
blockTypeEcPrivateKey = "EC PRIVATE KEY"
|
||||
)
|
||||
|
||||
func builtinCryptoX509ParseCertificates(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
@@ -52,7 +56,7 @@ func builtinCryptoX509ParseCertificates(_ BuiltinContext, operands []*ast.Term,
|
||||
return err
|
||||
}
|
||||
|
||||
v, err := ast.InterfaceToValue(certs)
|
||||
v, err := ast.InterfaceToValue(extendCertificates(certs))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -60,6 +64,28 @@ func builtinCryptoX509ParseCertificates(_ BuiltinContext, operands []*ast.Term,
|
||||
return iter(ast.NewTerm(v))
|
||||
}
|
||||
|
||||
// extendedCert is a wrapper around x509.Certificate that adds additional fields for JSON serialization.
|
||||
type extendedCert struct {
|
||||
x509.Certificate
|
||||
URIStrings []string
|
||||
}
|
||||
|
||||
func extendCertificates(certs []*x509.Certificate) []extendedCert {
|
||||
// add a field to certs containing the URIs as strings
|
||||
processedCerts := make([]extendedCert, len(certs))
|
||||
|
||||
for i, cert := range certs {
|
||||
processedCerts[i].Certificate = *cert
|
||||
if cert.URIs != nil {
|
||||
processedCerts[i].URIStrings = make([]string, len(cert.URIs))
|
||||
for j, uri := range cert.URIs {
|
||||
processedCerts[i].URIStrings[j] = uri.String()
|
||||
}
|
||||
}
|
||||
}
|
||||
return processedCerts
|
||||
}
|
||||
|
||||
func builtinCryptoX509ParseAndVerifyCertificates(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
|
||||
a := operands[0].Value
|
||||
@@ -83,7 +109,7 @@ func builtinCryptoX509ParseAndVerifyCertificates(_ BuiltinContext, operands []*a
|
||||
return iter(invalid)
|
||||
}
|
||||
|
||||
value, err := ast.InterfaceToValue(verified)
|
||||
value, err := ast.InterfaceToValue(extendCertificates(verified))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -96,6 +122,29 @@ func builtinCryptoX509ParseAndVerifyCertificates(_ BuiltinContext, operands []*a
|
||||
return iter(valid)
|
||||
}
|
||||
|
||||
func builtinCryptoX509ParseKeyPair(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
certificate, err := builtins.StringOperand(operands[0].Value, 1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
key, err := builtins.StringOperand(operands[1].Value, 1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
certs, err := getTLSx509KeyPairFromString([]byte(certificate), []byte(key))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
v, err := ast.InterfaceToValue(certs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return iter(ast.NewTerm(v))
|
||||
}
|
||||
|
||||
func builtinCryptoX509ParseCertificateRequest(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
input, err := builtins.StringOperand(operands[0].Value, 1)
|
||||
if err != nil {
|
||||
@@ -144,7 +193,8 @@ func builtinCryptoX509ParseCertificateRequest(_ BuiltinContext, operands []*ast.
|
||||
return iter(ast.NewTerm(v))
|
||||
}
|
||||
|
||||
func builtinCryptoX509ParseRSAPrivateKey(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
func builtinCryptoJWKFromPrivateKey(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
var x interface{}
|
||||
|
||||
a := operands[0].Value
|
||||
input, err := builtins.StringOperand(a, 1)
|
||||
@@ -153,23 +203,83 @@ func builtinCryptoX509ParseRSAPrivateKey(_ BuiltinContext, operands []*ast.Term,
|
||||
}
|
||||
|
||||
// get the raw private key
|
||||
rawKey, err := getRSAPrivateKeyFromString(string(input))
|
||||
pemDataString := string(input)
|
||||
|
||||
if pemDataString == "" {
|
||||
return fmt.Errorf("input PEM data was empty")
|
||||
}
|
||||
|
||||
// This built in must be supplied a valid PEM or base64 encoded string.
|
||||
// If the input is not a PEM string, attempt to decode b64.
|
||||
// If the base64 decode fails - this is an error
|
||||
if !strings.HasPrefix(pemDataString, "-----BEGIN") {
|
||||
bs, err := base64.StdEncoding.DecodeString(pemDataString)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pemDataString = string(bs)
|
||||
}
|
||||
|
||||
rawKeys, err := getPrivateKeysFromPEMData(pemDataString)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rsaPrivateKey, err := jwk.New(rawKey)
|
||||
if len(rawKeys) == 0 {
|
||||
return iter(ast.NullTerm())
|
||||
}
|
||||
|
||||
key, err := jwk.New(rawKeys[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
jsonKey, err := json.Marshal(rsaPrivateKey)
|
||||
jsonKey, err := json.Marshal(key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := util.UnmarshalJSON(jsonKey, &x); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
value, err := ast.InterfaceToValue(x)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return iter(ast.NewTerm(value))
|
||||
}
|
||||
|
||||
func builtinCryptoParsePrivateKeys(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
|
||||
a := operands[0].Value
|
||||
input, err := builtins.StringOperand(a, 1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if string(input) == "" {
|
||||
return iter(ast.NullTerm())
|
||||
}
|
||||
|
||||
// get the raw private key
|
||||
rawKeys, err := getPrivateKeysFromPEMData(string(input))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(rawKeys) == 0 {
|
||||
return iter(ast.NewTerm(ast.NewArray()))
|
||||
}
|
||||
|
||||
bs, err := json.Marshal(rawKeys)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var x interface{}
|
||||
if err := util.UnmarshalJSON(jsonKey, &x); err != nil {
|
||||
if err := util.UnmarshalJSON(bs, &x); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -249,6 +359,24 @@ func builtinCryptoHmacSha512(_ BuiltinContext, operands []*ast.Term, iter func(*
|
||||
return hmacHelper(operands, iter, sha512.New)
|
||||
}
|
||||
|
||||
func builtinCryptoHmacEqual(_ BuiltinContext, operands []*ast.Term, iter func(*ast.Term) error) error {
|
||||
a1 := operands[0].Value
|
||||
mac1, err := builtins.StringOperand(a1, 1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
a2 := operands[1].Value
|
||||
mac2, err := builtins.StringOperand(a2, 2)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
res := hmac.Equal([]byte(mac1), []byte(mac2))
|
||||
|
||||
return iter(ast.BooleanTerm(res))
|
||||
}
|
||||
|
||||
func init() {
|
||||
RegisterBuiltinFunc(ast.CryptoX509ParseCertificates.Name, builtinCryptoX509ParseCertificates)
|
||||
RegisterBuiltinFunc(ast.CryptoX509ParseAndVerifyCertificates.Name, builtinCryptoX509ParseAndVerifyCertificates)
|
||||
@@ -256,11 +384,14 @@ func init() {
|
||||
RegisterBuiltinFunc(ast.CryptoSha1.Name, builtinCryptoSha1)
|
||||
RegisterBuiltinFunc(ast.CryptoSha256.Name, builtinCryptoSha256)
|
||||
RegisterBuiltinFunc(ast.CryptoX509ParseCertificateRequest.Name, builtinCryptoX509ParseCertificateRequest)
|
||||
RegisterBuiltinFunc(ast.CryptoX509ParseRSAPrivateKey.Name, builtinCryptoX509ParseRSAPrivateKey)
|
||||
RegisterBuiltinFunc(ast.CryptoX509ParseRSAPrivateKey.Name, builtinCryptoJWKFromPrivateKey)
|
||||
RegisterBuiltinFunc(ast.CryptoParsePrivateKeys.Name, builtinCryptoParsePrivateKeys)
|
||||
RegisterBuiltinFunc(ast.CryptoX509ParseKeyPair.Name, builtinCryptoX509ParseKeyPair)
|
||||
RegisterBuiltinFunc(ast.CryptoHmacMd5.Name, builtinCryptoHmacMd5)
|
||||
RegisterBuiltinFunc(ast.CryptoHmacSha1.Name, builtinCryptoHmacSha1)
|
||||
RegisterBuiltinFunc(ast.CryptoHmacSha256.Name, builtinCryptoHmacSha256)
|
||||
RegisterBuiltinFunc(ast.CryptoHmacSha512.Name, builtinCryptoHmacSha512)
|
||||
RegisterBuiltinFunc(ast.CryptoHmacEqual.Name, builtinCryptoHmacEqual)
|
||||
}
|
||||
|
||||
func verifyX509CertificateChain(certs []*x509.Certificate) ([]*x509.Certificate, error) {
|
||||
@@ -334,43 +465,56 @@ func getX509CertsFromPem(pemBlocks []byte) ([]*x509.Certificate, error) {
|
||||
return x509.ParseCertificates(decodedCerts)
|
||||
}
|
||||
|
||||
func getRSAPrivateKeyFromString(key string) (interface{}, error) {
|
||||
// if the input is PEM handle that
|
||||
if strings.HasPrefix(key, "-----BEGIN") {
|
||||
return getRSAPrivateKeyFromPEM([]byte(key))
|
||||
func getPrivateKeysFromPEMData(pemData string) ([]crypto.PrivateKey, error) {
|
||||
pemBlockString := pemData
|
||||
|
||||
var validPrivateKeys []crypto.PrivateKey
|
||||
|
||||
// if the input is base64, decode it
|
||||
bs, err := base64.StdEncoding.DecodeString(pemBlockString)
|
||||
if err == nil {
|
||||
pemBlockString = string(bs)
|
||||
}
|
||||
bs = []byte(pemBlockString)
|
||||
|
||||
// assume input is base64 if not PEM
|
||||
b64, err := base64.StdEncoding.DecodeString(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
for len(bs) > 0 {
|
||||
inputLen := len(bs)
|
||||
var block *pem.Block
|
||||
block, bs = pem.Decode(bs)
|
||||
if block == nil && len(bs) == 0 {
|
||||
break
|
||||
}
|
||||
// should only happen if end of input is not a valid PEM block. See TestParseRSAPrivateKeyVariedPemInput.
|
||||
if inputLen == len(bs) {
|
||||
break
|
||||
}
|
||||
|
||||
if block == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
switch block.Type {
|
||||
case blockTypeRSAPrivateKey:
|
||||
parsedKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
validPrivateKeys = append(validPrivateKeys, parsedKey)
|
||||
case blockTypePrivateKey:
|
||||
parsedKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
validPrivateKeys = append(validPrivateKeys, parsedKey)
|
||||
case blockTypeEcPrivateKey:
|
||||
parsedKey, err := x509.ParseECPrivateKey(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
validPrivateKeys = append(validPrivateKeys, parsedKey)
|
||||
}
|
||||
}
|
||||
|
||||
return getRSAPrivateKeyFromPEM(b64)
|
||||
}
|
||||
|
||||
func getRSAPrivateKeyFromPEM(pemBlocks []byte) (interface{}, error) {
|
||||
|
||||
// decode the pem into the Block struct
|
||||
p, _ := pem.Decode(pemBlocks)
|
||||
if p == nil {
|
||||
return nil, fmt.Errorf("failed to parse PEM block containing the key")
|
||||
}
|
||||
|
||||
// if the key is in PKCS1 format
|
||||
if p.Type == blockTypeRSAPrivateKey {
|
||||
return x509.ParsePKCS1PrivateKey(p.Bytes)
|
||||
}
|
||||
|
||||
// if the key is in PKCS8 format
|
||||
if p.Type == blockTypePrivateKey {
|
||||
return x509.ParsePKCS8PrivateKey(p.Bytes)
|
||||
}
|
||||
|
||||
// unsupported key format
|
||||
return nil, fmt.Errorf("PEM block type is '%s', expected %s or %s", p.Type, blockTypeRSAPrivateKey,
|
||||
blockTypePrivateKey)
|
||||
|
||||
return validPrivateKeys, nil
|
||||
}
|
||||
|
||||
// addCACertsFromFile adds CA certificates from filePath into the given pool.
|
||||
@@ -406,7 +550,7 @@ func addCACertsFromBytes(pool *x509.CertPool, pemBytes []byte) (*x509.CertPool,
|
||||
return pool, nil
|
||||
}
|
||||
|
||||
// addCACertsFromBytes adds CA certificates from the environment variable named
|
||||
// addCACertsFromEnv adds CA certificates from the environment variable named
|
||||
// by envName into the given pool. If pool is nil, it creates a new x509.CertPool.
|
||||
// pool is returned.
|
||||
func addCACertsFromEnv(pool *x509.CertPool, envName string) (*x509.CertPool, error) {
|
||||
@@ -428,6 +572,60 @@ func readCertFromFile(localCertFile string) ([]byte, error) {
|
||||
return certPEM, nil
|
||||
}
|
||||
|
||||
func getTLSx509KeyPairFromString(certPemBlock []byte, keyPemBlock []byte) (*tls.Certificate, error) {
|
||||
|
||||
if !strings.HasPrefix(string(certPemBlock), "-----BEGIN") {
|
||||
s, err := base64.StdEncoding.DecodeString(string(certPemBlock))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
certPemBlock = s
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(string(keyPemBlock), "-----BEGIN") {
|
||||
s, err := base64.StdEncoding.DecodeString(string(keyPemBlock))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
keyPemBlock = s
|
||||
}
|
||||
|
||||
// we assume it a DER certificate and try to convert it to a PEM.
|
||||
if !bytes.HasPrefix(certPemBlock, []byte("-----BEGIN")) {
|
||||
|
||||
pemBlock := &pem.Block{
|
||||
Type: "CERTIFICATE",
|
||||
Bytes: certPemBlock,
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
if err := pem.Encode(&buf, pemBlock); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
certPemBlock = buf.Bytes()
|
||||
|
||||
}
|
||||
// we assume it a DER key and try to convert it to a PEM.
|
||||
if !bytes.HasPrefix(keyPemBlock, []byte("-----BEGIN")) {
|
||||
pemBlock := &pem.Block{
|
||||
Type: "PRIVATE KEY",
|
||||
Bytes: keyPemBlock,
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
if err := pem.Encode(&buf, pemBlock); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
keyPemBlock = buf.Bytes()
|
||||
}
|
||||
|
||||
cert, err := tls.X509KeyPair(certPemBlock, keyPemBlock)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &cert, nil
|
||||
}
|
||||
|
||||
// ReadKeyFromFile reads a key from file
|
||||
func readKeyFromFile(localKeyFile string) ([]byte, error) {
|
||||
// Read in the cert file
|
||||
|
||||
Reference in New Issue
Block a user