maddy

Fork https://github.com/foxcpp/maddy

git clone git://git.lin.moe/go/maddy.git

  1/*
  2Maddy Mail Server - Composable all-in-one email server.
  3Copyright © 2019-2020 Max Mazurov <fox.cpp@disroot.org>, Maddy Mail Server contributors
  4
  5This program is free software: you can redistribute it and/or modify
  6it under the terms of the GNU General Public License as published by
  7the Free Software Foundation, either version 3 of the License, or
  8(at your option) any later version.
  9
 10This program is distributed in the hope that it will be useful,
 11but WITHOUT ANY WARRANTY; without even the implied warranty of
 12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 13GNU General Public License for more details.
 14
 15You should have received a copy of the GNU General Public License
 16along with this program.  If not, see <https://www.gnu.org/licenses/>.
 17*/
 18
 19package dkim
 20
 21import (
 22	"crypto/ed25519"
 23	"crypto/rsa"
 24	"encoding/base64"
 25	"os"
 26	"path/filepath"
 27	"strings"
 28	"testing"
 29
 30	"github.com/foxcpp/maddy/internal/testutils"
 31)
 32
 33func TestKeyLoad_new(t *testing.T) {
 34	m := Modifier{}
 35	m.log = testutils.Logger(t, m.Name())
 36
 37	dir := t.TempDir()
 38
 39	signer, newKey, err := m.loadOrGenerateKey(filepath.Join(dir, "testkey.key"), "ed25519")
 40	if err != nil {
 41		t.Fatal(err)
 42	}
 43	if !newKey {
 44		t.Fatal("newKey=false")
 45	}
 46
 47	recordBlob, err := os.ReadFile(filepath.Join(dir, "testkey.dns"))
 48	if err != nil {
 49		t.Fatal(err)
 50	}
 51	var keyBlob []byte
 52	for _, part := range strings.Split(string(recordBlob), ";") {
 53		part = strings.TrimSpace(part)
 54		if strings.HasPrefix(part, "k=") {
 55			if part != "k=ed25519" {
 56				t.Fatalf("Wrong type of generated key, want ed25519, got %s", part)
 57			}
 58		}
 59		if strings.HasPrefix(part, "p=") {
 60			keyBlob, err = base64.StdEncoding.DecodeString(part[2:])
 61			if err != nil {
 62				t.Fatal(err)
 63			}
 64		}
 65	}
 66
 67	blob := signer.Public().(ed25519.PublicKey)
 68	if string(blob) != string(keyBlob) {
 69		t.Fatal("wrong public key placed into record file")
 70	}
 71}
 72
 73const pkeyEd25519 = `-----BEGIN PRIVATE KEY-----
 74MC4CAQAwBQYDK2VwBCIEIJG9zs4vi2MYNkL9gUQwlmBLCzDODIJ5/1CwTAZFDm5U
 75-----END PRIVATE KEY-----`
 76
 77const pubkeyEd25519 = `5TPcCxzVByMyRsMFs5Dx23pnxKilI+1UrGg0t+O2oZU=`
 78
 79func TestKeyLoad_existing_pkcs8(t *testing.T) {
 80	m := Modifier{}
 81	m.log = testutils.Logger(t, m.Name())
 82
 83	dir := t.TempDir()
 84
 85	if err := os.WriteFile(filepath.Join(dir, "testkey.key"), []byte(pkeyEd25519), 0o600); err != nil {
 86		t.Fatal(err)
 87	}
 88
 89	signer, newKey, err := m.loadOrGenerateKey(filepath.Join(dir, "testkey.key"), "ed25519")
 90	if err != nil {
 91		t.Fatal(err)
 92	}
 93	if newKey {
 94		t.Fatal("newKey = true")
 95	}
 96
 97	blob := signer.Public().(ed25519.PublicKey)
 98	if signerKey := base64.StdEncoding.EncodeToString(blob); signerKey != pubkeyEd25519 {
 99		t.Fatalf("wrong public key returned by loadOrGenerateKey, \nwant %s\ngot  %s", pubkeyEd25519, signerKey)
100	}
101}
102
103const pkeyRSA = `-----BEGIN RSA PRIVATE KEY-----
104MIIEowIBAAKCAQEAuxWwDR9ADiuV2b9xF+btOIgwS5W0yJeS/Dht4HlUELrye2JZ
1057TCQpx2Hs1FY5Tkj4VLnYHTPftS6cLYNx6hQbWZMhj5qmP9ccQ8rqdgdLB5RqCn3
106zo8wbKFZ8ygYt1yZyNOfJLNTBjIcC1BCKoZosA7MWHUOwRtt1ARVmldsNH3iio0l
107wHjyKNYd0Kqw4uGEg6sulK69lw4G8YTnKtCt0G8vCpQHyQepolOMF7Q1NZEw02/U
108E54qgaaC+ym+BQsqqF5iodmuIfLX+W0kKDee2YYhjuxNaFcPhE5j35LlGHCsrL0X
109h4+2VZSYXuAO5aWpwX9jrrSFyCJLD/aYGMgdrwIDAQABAoIBAEZrF2UZCidLSJA5
110evwgM9I/kM4if3Wxd+Xv54vCn13cwECo+GhLC2ebueRJDkjZhSPe7LBlx2RZ9gNO
111w0kPlZZYFx3AiKcmF0mHCExZyEE++EVv5pKdWwDIiu73fLYn6MqqvRA3X1zJp7yq
112bP1MskLyjwAMr40IIgLXztDVbykiRC2Rw+o5cu7o3e0p0sFqJsjCUKtXZuzLePOk
113gYYZ4FsmmVYh7pf244NEQao+fT19RtFL85E17yAHv+YD7qUBdbxoWIuAher9N/C0
114vOj4xYbNxbkS0+BTbygLAog5mFtNbAGysUZZ3YOYfKYgj9/u+aKwr2ZS2zIEeJj0
115eAiHtWECgYEA48dqxrR76JyukHid+XyI4Nqt+2EHEeDi23WTTT6lSZL1F3I2q7FF
116DSHOA3hGw57GAMNQYCSzYxC4TBpZwJ7/8NdhA/kJg7tLOqcvZtS3Bu5bzLqLOCqL
117E1tgh2LrpWjit2v+VSsQlf+QjG7QAEiWtya+AOfNWenILfxk2VNPP3MCgYEA0kOM
118ym/EcgcSSihbFyyYO4UHZZ7rWiPRB+BtatJbEADMXMlwSAXvvVCpWSZBKBKjIE2y
119ZM+kvv50QUd4ue7dKVEnqOy26XuAmuTE14smx1QyNonRvBV/HItJ0tKfMIZbXOpq
120S2ESXkFybCzdOfzWOhx0PHjr40w8XUeSZi0LodUCgYAsC8bhD8uaKpozA7AAq41I
121deEI6DVWxrb3mx/V4xRRSuKsGwDpaIkixfOxhhOhBlXhleM4BEDQGk6ZIMtUTSrO
1225scy3nhxick9WVD4QI/3/iWwTC5ZuRhVsOjUpVNOFB8rOu3eiEpXxyirj04Xj/Hd
123DtfVEv4JsgRsqA7UW6DKcwKBgQCiCvMXFDnWEwMSabWBz5lmzWfc9jO1HUM8Ccbp
124e0I4vBTDMW854nFXejF5BhVS18Il5BsmvCvgEePwZy9wQ9jnvaaN9hglKkv7k3Ds
125GE6DcazdASvFAuAaVHJJao7Ka9E/c10FyMLKJzASlCTOSr+iu0kNTbelTZx72uvF
126mNONHQKBgCEUuJMM11mV0FCsVfJsmIv6z/zqOiPiOVbP1Bv2WlVzipvkI9bm6OyN
127VHO8+oqFWyhJ3qRzebuPIefL8U6xjfMshX8MB23cB0J5LTPDZH3LCSmFvjr942EK
1285+ewYHKtmS+6aaE+J+oB11r7XU8FyEI0kv6rAPDwJ19K4BMG/x7J
129-----END RSA PRIVATE KEY-----`
130
131func TestKeyLoad_existing_pkcs1(t *testing.T) {
132	m := Modifier{}
133	m.log = testutils.Logger(t, m.Name())
134
135	dir := t.TempDir()
136
137	if err := os.WriteFile(filepath.Join(dir, "testkey.key"), []byte(pkeyRSA), 0o600); err != nil {
138		t.Fatal(err)
139	}
140
141	signer, newKey, err := m.loadOrGenerateKey(filepath.Join(dir, "testkey.key"), "rsa2048")
142	if err != nil {
143		t.Fatal(err)
144	}
145	if newKey {
146		t.Fatal("newKey=true")
147	}
148
149	pubkey := signer.Public().(*rsa.PublicKey)
150	if pubkey.E != 65537 {
151		t.Fatalf("wrong public key returned by loadOrGenerateKey, got %d", pubkey.E)
152	}
153	if pubkey.N.String() != "23617257632228188386824425094266725423560758883229529475904285522114491665694237598874002862630696077162868821164059728985148713872807170386818903503533709975391952347175641552635505497204925274569104682448177717429244936284920784061388978739927939000424446717818401440783667723710780854637197555911253613285419663410256437304926940168312631109994734698918250930969511949067760562140706765511288141008942649676427142664185811322596443990204153105455693515405445788622172538582060141770589195075185467867938584021491237815987395835392935511032761463924045865609068314478096903374718657496007822964380498648030935260591" {
154		t.Fatalf("wrong public key returned by loadOrGenerateKey, got %s", pubkey.N.String())
155	}
156}