Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
weinimo committed Sep 17, 2024
1 parent b46680b commit 38acf6e
Show file tree
Hide file tree
Showing 3 changed files with 167 additions and 5 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ require (
)

require (
github.com/pkg/errors v0.9.1
golang.org/x/crypto v0.26.0
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8
)
Expand Down Expand Up @@ -55,7 +56,6 @@ require (
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/openshift/api v3.9.0+incompatible // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/prometheus/client_golang v1.18.0 // indirect
github.com/prometheus/client_model v0.5.0 // indirect
github.com/prometheus/common v0.46.0 // indirect
Expand Down
5 changes: 1 addition & 4 deletions pkg/octavia/amphora_certs.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import (
"github.com/openstack-k8s-operators/lib-common/modules/common/helper"
"github.com/openstack-k8s-operators/lib-common/modules/common/secret"
octaviav1 "github.com/openstack-k8s-operators/octavia-operator/api/v1beta1"
"go.step.sm/crypto/pemutil"
corev1 "k8s.io/api/core/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -61,9 +60,7 @@ func generateKey(passphrase []byte) (*rsa.PrivateKey, []byte, error) {

var pemBlock *pem.Block
if passphrase != nil {
pemBlock, err = pemutil.EncryptPKCS8PrivateKey(
rand.Reader, pkcs8Key, passphrase, pemutil.DefaultEncCipher,
)
pemBlock, err = EncryptPrivateKey(pkcs8Key, passphrase)
if err != nil {
err = fmt.Errorf("Error encrypting private key: %w", err)
return priv, nil, err
Expand Down
165 changes: 165 additions & 0 deletions pkg/octavia/pkcs8_aes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
/*
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 octavia

import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"crypto/sha256"
"encoding/asn1"
"encoding/pem"
"fmt"

"github.com/pkg/errors"
"golang.org/x/crypto/pbkdf2"
)

var (
// key derivation functions
oidPKCS5PBKDF2 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 5, 12}
oidPBES2 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 5, 13}
oidHMACWithSHA256 = asn1.ObjectIdentifier{1, 2, 840, 113549, 2, 9}

// encryption
oidAES256CBC = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 1, 42}
)

// Encrypted pkcs8
// Based on https://github.com/youmark/pkcs8
// MIT license
type prfParam struct {
Algo asn1.ObjectIdentifier
NullParam asn1.RawValue
}

type pbkdf2Params struct {
Salt []byte
IterationCount int
PrfParam prfParam `asn1:"optional"`
}

type pbkdf2Algorithms struct {
Algo asn1.ObjectIdentifier
PBKDF2Params pbkdf2Params
}

type pbkdf2Encs struct {
EncryAlgo asn1.ObjectIdentifier
IV []byte
}

type pbes2Params struct {
KeyDerivationFunc pbkdf2Algorithms
EncryptionScheme pbkdf2Encs
}

type encryptedlAlgorithmIdentifier struct {
Algorithm asn1.ObjectIdentifier
Parameters pbes2Params
}

type encryptedPrivateKeyInfo struct {
Algo encryptedlAlgorithmIdentifier
PrivateKey []byte
}

func EncryptPrivateKey(data, password []byte) (*pem.Block, error) {
pbkdf2_iterations := 600000
aes256_keysize := 32
aes256_blocksize := aes.BlockSize
data_length := len(data)
pad_size := aes256_blocksize - data_length%aes256_blocksize
// encrypted_size := data_length + pad_size

// Generate salt using random data
pbkdf2_salt := make([]byte, 16)
_, err := rand.Read(pbkdf2_salt)
if err != nil {
err = fmt.Errorf("error generating random data for salt for private key encryption: %w", err)
return nil, err
}

iv := make([]byte, aes256_blocksize)
_, err = rand.Read(iv)
if err != nil {
err = fmt.Errorf("error generating random data for init vector for private key encryption: %w", err)
return nil, err
}

key := pbkdf2.Key(password, pbkdf2_salt, pbkdf2_iterations,
aes256_keysize, sha256.New)
encrypted_block, err := aes.NewCipher(key)
if err != nil {
err = fmt.Errorf("error creating new cipher block for private key encryption: %w", err)
return nil, err
}

// crypt_source := make([]byte, encrypted_size)
// copy(crypt_source, data)
// // Set padding data according to RFC1423, 1.1
// for i := data_length; i < encrypted_size; i++ {
// crypt_source[i] = byte(pad_size)
// }
// encrypted := make([]byte, encrypted_size)

// encrypter := cipher.NewCBCEncrypter(encrypted_block, iv)
// encrypter.CryptBlocks(encrypted, crypt_source)

encrypted := make([]byte, len(data), len(data)+pad_size)
// We could save this copy by encrypting all the whole blocks in
// the data separately, but it doesn't seem worth the additional
// code.
copy(encrypted, data)
// See RFC 1423, section 1.1
for i := 0; i < pad_size; i++ {
encrypted = append(encrypted, byte(pad_size))
}
encrypter := cipher.NewCBCEncrypter(encrypted_block, iv)
encrypter.CryptBlocks(encrypted, encrypted)

// Build encrypted ans1 data
pki := encryptedPrivateKeyInfo{
Algo: encryptedlAlgorithmIdentifier{
Algorithm: oidPBES2,
Parameters: pbes2Params{
KeyDerivationFunc: pbkdf2Algorithms{
Algo: oidPKCS5PBKDF2,
PBKDF2Params: pbkdf2Params{
Salt: pbkdf2_salt,
IterationCount: pbkdf2_iterations,
PrfParam: prfParam{
Algo: oidHMACWithSHA256,
},
},
},
EncryptionScheme: pbkdf2Encs{
EncryAlgo: oidAES256CBC,
IV: iv,
},
},
},
PrivateKey: encrypted,
}

b, err := asn1.Marshal(pki)
if err != nil {
return nil, errors.Wrap(err, "error marshaling encrypted key")
}
return &pem.Block{
Type: "ENCRYPTED PRIVATE KEY",
Bytes: b,
}, nil
}

0 comments on commit 38acf6e

Please sign in to comment.