diff --git a/internal/selfhosted/keys.go b/internal/selfhosted/keys.go index 9a961df..a72c652 100644 --- a/internal/selfhosted/keys.go +++ b/internal/selfhosted/keys.go @@ -5,48 +5,36 @@ import ( "crypto/rsa" "crypto/x509" "encoding/pem" - "os" ) -func createKeyPair() error { - // RSAキーペアの生成 +type KeyPair struct { + PublicKey []byte + PrivateKey []byte +} + +func createKeyPair() (*KeyPair, error) { privateKey, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { - return err + return nil, err } - // private keyをPEM形式で保存 + // convert private key to PEM privPem := pem.Block{ Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(privateKey), } - privPemFile, err := os.Create("private_key.pem") - if err != nil { - return err - } - defer privPemFile.Close() - if err := pem.Encode(privPemFile, &privPem); err != nil { - return err - } + privPemBytes := pem.EncodeToMemory(&privPem) - // 公開鍵をPKIX, ASN.1 DER形式に変換 + // convert public key to PKIX, ASN.1 DER pubASN1, err := x509.MarshalPKIXPublicKey(&privateKey.PublicKey) if err != nil { - return err + return nil, err } - // 公開鍵をPEM形式で保存 pubPem := pem.Block{ Type: "PUBLIC KEY", Bytes: pubASN1, } - pubPemFile, err := os.Create("public_key.pem") - if err != nil { - return err - } - defer pubPemFile.Close() - if err := pem.Encode(pubPemFile, &pubPem); err != nil { - return err - } - return nil + pubPemBytes := pem.EncodeToMemory(&pubPem) + return &KeyPair{pubPemBytes, privPemBytes}, nil } diff --git a/internal/selfhosted/keys_test.go b/internal/selfhosted/keys_test.go index 7b2a4ea..1c2c4ec 100644 --- a/internal/selfhosted/keys_test.go +++ b/internal/selfhosted/keys_test.go @@ -1,43 +1,44 @@ package selfhosted import ( - "os" + "crypto" + "crypto/rand" + "crypto/rsa" + "crypto/sha256" + "crypto/x509" + "encoding/pem" "testing" "github.com/stretchr/testify/assert" ) -const rsaKeyID = "JHJehTTTZlsspKHT-GaJxK7Kd1NQgZJu3fyK6K_QDYU" - func TestReadKey(t *testing.T) { - tests := []struct { - name string - filename string - expected string - expectErr bool - }{ - { - name: "rsa", - filename: "testdata/rsa.pub", - expected: rsaKeyID, - }, - { - name: "rsa", - filename: "testdata/ecdsa.pub", - expectErr: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - content, err := os.ReadFile(tt.filename) - assert.NoError(t, err) - actual, err := NewJWK(content) - if tt.expectErr { - assert.Error(t, err, "") - } else { - assert.NoError(t, err) - assert.Equal(t, tt.expected, actual.Keys[0].KeyID) - } - }) - } + t.Run("key pair check", func(t *testing.T) { + keyPair, err := createKeyPair() + assert.NoError(t, err) + + message := []byte("test message") + hashed := sha256.Sum256(message) + + block, _ := pem.Decode(keyPair.PrivateKey) + assert.NotNil(t, block, "failed to decode private key to PEM") + + privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes) + assert.NoError(t, err, "failed to parse private key") + + signature, err := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, hashed[:]) + + assert.NoError(t, err, "failed to create signature") + block, _ = pem.Decode(keyPair.PublicKey) + assert.NotNil(t, block, "failed to decode public key to PEM") + + pubKey, err := x509.ParsePKIXPublicKey(block.Bytes) + assert.NoError(t, err, "failed to parse public key") + + rsaPubKey, ok := pubKey.(*rsa.PublicKey) + assert.Truef(t, ok, "public key is not RSA") + + err = rsa.VerifyPKCS1v15(rsaPubKey, crypto.SHA256, hashed[:], signature) + assert.NoError(t, err, "failed to check signature") + }) }