certmanager updated
This commit is contained in:
42
pkg/cm509/testchain_a00.crt
Normal file
42
pkg/cm509/testchain_a00.crt
Normal file
@@ -0,0 +1,42 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIHZDCCBkygAwIBAgISA0TPqlhFqMMjfL8lwr1WdKCiMA0GCSqGSIb3DQEBCwUA
|
||||
MDMxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQwwCgYDVQQD
|
||||
EwNSMTEwHhcNMjQwNzE1MDcwNTQyWhcNMjQxMDEzMDcwNTQxWjAYMRYwFAYDVQQD
|
||||
Ew1oYW0udW5peDcub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
|
||||
xDw3k4983QmRIqV0PsXFfG3x1wkamrMrY9sMz+M+CR9h1iozv4OQdm5wFJp/8ert
|
||||
7x+JS07v4vabYoLyVsdteRXHrqXlSDJMuZaReHIQVqKk1BYZ9miIH64ExUA6vd3r
|
||||
8AmilipIPW+UJihaZnP7wPy80PUdCiq0tnSewKN+wfzka5yehWXeaTbDeDoUl1Cf
|
||||
5Q3CO9KhbIYNwG8GBm+4YKiuewjjIU4sPEaCPvpvCTcwA4Lcqf1awU/nRdTLXO1e
|
||||
L4LezTEPb7KSS7hEZSHs2aQbjVpoV0IcuSYI1beb7XSdsv/jDIzOpu/Sx+AqMUy+
|
||||
WE4sO0Yj3ap8mbsY9HTC7QIDAQABo4IEizCCBIcwDgYDVR0PAQH/BAQDAgWgMB0G
|
||||
A1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMB0GA1Ud
|
||||
DgQWBBR3smydoErE3KVUBr0/ohKZ0ghK0jAfBgNVHSMEGDAWgBTFz0ak6vTDwHps
|
||||
lcQtsF6SLybjuTBXBggrBgEFBQcBAQRLMEkwIgYIKwYBBQUHMAGGFmh0dHA6Ly9y
|
||||
MTEuby5sZW5jci5vcmcwIwYIKwYBBQUHMAKGF2h0dHA6Ly9yMTEuaS5sZW5jci5v
|
||||
cmcvMIICkAYDVR0RBIIChzCCAoOCEmFpcmZvcmNlLnVuaXg3Lm9yZ4IOYXJ0cy51
|
||||
bml4Ny5vcmeCDWRlNC51bml4Ny5vcmeCDWRlNS51bml4Ny5vcmeCDWRlNi51bml4
|
||||
Ny5vcmeCDWRlNy51bml4Ny5vcmeCDWRlYi51bml4Ny5vcmeCDWRldi51bml4Ny5v
|
||||
cmeCDmRuczUudW5peDcub3Jngg1lZHUudW5peDcub3JnghBlZHVtYXgudW5peDcu
|
||||
b3Jngg1naXQudW5peDcub3Jngg9nbWFpbC51bml4Ny5vcmeCDWhhbS51bml4Ny5v
|
||||
cmeCDmhhc2gudW5peDcub3JnggxoZC51bml4Ny5vcmeCDmhlYXAudW5peDcub3Jn
|
||||
ghJob21lZGVzay51bml4Ny5vcmeCDWh1Yi51bml4Ny5vcmeCEGl0ZGVzay51bml4
|
||||
Ny5vcmeCD2xhcGlzLnVuaXg3Lm9yZ4IPbG9yZW0udW5peDcub3Jngg5tYWlsLnVu
|
||||
aXg3Lm9yZ4IMbXcudW5peDcub3JnggxteC51bml4Ny5vcmeCDnBkbnMudW5peDcu
|
||||
b3Jngg5waWtpLnVuaXg3Lm9yZ4IPcHJveHkudW5peDcub3JnghFyZWRtaW5lLnVu
|
||||
aXg3Lm9yZ4IMcm0udW5peDcub3Jngg9zbGFjay51bml4Ny5vcmeCEHNwcmluZy51
|
||||
bml4Ny5vcmeCDnNydjcudW5peDcub3JnghBzdG9yZXgudW5peDcub3JnghB0YW5h
|
||||
a2gudW5peDcub3Jnggx2NS51bml4Ny5vcmeCDXcxMi51bml4Ny5vcmeCDXdjbS51
|
||||
bml4Ny5vcmeCDndpa2kudW5peDcub3Jngg13d3cudW5peDcub3JnMBMGA1UdIAQM
|
||||
MAowCAYGZ4EMAQIBMIIBBAYKKwYBBAHWeQIEAgSB9QSB8gDwAHcASLDja9qmRzQP
|
||||
5WoC+p0w6xxSActW3SyB2bu/qznYhHMAAAGQtW0RVQAABAMASDBGAiEAjQvvzpOR
|
||||
urMOiqV5g0EuAK1A9CuAKOdWJp6/s3/SKBMCIQCbTBj13lhMnTr6bSHwoBtSwoiY
|
||||
aeDJzGBmDTpbgGpFdQB1AN/hVuuqBa+1nA+GcY2owDJOrlbZbqf1pWoB0cE7vlJc
|
||||
AAABkLVtEicAAAQDAEYwRAIgWe0pdXXB6UmMmeSgYLDncdkS2aKHAHDdOqKOoL9x
|
||||
Kx8CIBqobR/Ve1IZMTLrRN54vh8kNmF0OkVjXtrh+ste6cKUMA0GCSqGSIb3DQEB
|
||||
CwUAA4IBAQA3c88cXIejS9vy4XUow6dOuud6qqkNX1osSq2vRtYkKMZb2JVuhPAr
|
||||
hQsozwptJPm5lOEDQPD8676yZNVgGdjmMvA0ewdWEp9HZ7x+RFlI7RC9CqMSOWPO
|
||||
p60RMiBQlK7Els38WurmW2GzZkfykzpZZ/0lIrCNjT7aB9VjGVDOjxo/xHapHSwJ
|
||||
GOxq4TTU1KaFfbFl5A2F9bRVrAAWfih+DzUzhlhZBHODzadgs2CimVYIp8gEVf1j
|
||||
dGetiU2j+cvOpvQnfX7Xr8Cf2YK7E0j6lfC3RPvK9oA1bP5KBMWELXsGBrwIxgUB
|
||||
f2/jRcxrQoGoEYwYW4D/JViKwelABzfc
|
||||
-----END CERTIFICATE-----
|
||||
29
pkg/cm509/testchain_a01.crt
Normal file
29
pkg/cm509/testchain_a01.crt
Normal file
@@ -0,0 +1,29 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFBjCCAu6gAwIBAgIRAIp9PhPWLzDvI4a9KQdrNPgwDQYJKoZIhvcNAQELBQAw
|
||||
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
|
||||
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjQwMzEzMDAwMDAw
|
||||
WhcNMjcwMzEyMjM1OTU5WjAzMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg
|
||||
RW5jcnlwdDEMMAoGA1UEAxMDUjExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
|
||||
CgKCAQEAuoe8XBsAOcvKCs3UZxD5ATylTqVhyybKUvsVAbe5KPUoHu0nsyQYOWcJ
|
||||
DAjs4DqwO3cOvfPlOVRBDE6uQdaZdN5R2+97/1i9qLcT9t4x1fJyyXJqC4N0lZxG
|
||||
AGQUmfOx2SLZzaiSqhwmej/+71gFewiVgdtxD4774zEJuwm+UE1fj5F2PVqdnoPy
|
||||
6cRms+EGZkNIGIBloDcYmpuEMpexsr3E+BUAnSeI++JjF5ZsmydnS8TbKF5pwnnw
|
||||
SVzgJFDhxLyhBax7QG0AtMJBP6dYuC/FXJuluwme8f7rsIU5/agK70XEeOtlKsLP
|
||||
Xzze41xNG/cLJyuqC0J3U095ah2H2QIDAQABo4H4MIH1MA4GA1UdDwEB/wQEAwIB
|
||||
hjAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwEgYDVR0TAQH/BAgwBgEB
|
||||
/wIBADAdBgNVHQ4EFgQUxc9GpOr0w8B6bJXELbBeki8m47kwHwYDVR0jBBgwFoAU
|
||||
ebRZ5nu25eQBc4AIiMgaWPbpm24wMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzAC
|
||||
hhZodHRwOi8veDEuaS5sZW5jci5vcmcvMBMGA1UdIAQMMAowCAYGZ4EMAQIBMCcG
|
||||
A1UdHwQgMB4wHKAaoBiGFmh0dHA6Ly94MS5jLmxlbmNyLm9yZy8wDQYJKoZIhvcN
|
||||
AQELBQADggIBAE7iiV0KAxyQOND1H/lxXPjDj7I3iHpvsCUf7b632IYGjukJhM1y
|
||||
v4Hz/MrPU0jtvfZpQtSlET41yBOykh0FX+ou1Nj4ScOt9ZmWnO8m2OG0JAtIIE38
|
||||
01S0qcYhyOE2G/93ZCkXufBL713qzXnQv5C/viOykNpKqUgxdKlEC+Hi9i2DcaR1
|
||||
e9KUwQUZRhy5j/PEdEglKg3l9dtD4tuTm7kZtB8v32oOjzHTYw+7KdzdZiw/sBtn
|
||||
UfhBPORNuay4pJxmY/WrhSMdzFO2q3Gu3MUBcdo27goYKjL9CTF8j/Zz55yctUoV
|
||||
aneCWs/ajUX+HypkBTA+c8LGDLnWO2NKq0YD/pnARkAnYGPfUDoHR9gVSp/qRx+Z
|
||||
WghiDLZsMwhN1zjtSC0uBWiugF3vTNzYIEFfaPG7Ws3jDrAMMYebQ95JQ+HIBD/R
|
||||
PBuHRTBpqKlyDnkSHDHYPiNX3adPoPAcgdF3H2/W0rmoswMWgTlLn1Wu0mrks7/q
|
||||
pdWfS6PJ1jty80r2VKsM/Dj3YIDfbjXKdaFU5C+8bhfJGqU3taKauuz0wHVGT3eo
|
||||
6FlWkWYtbt4pgdamlwVeZEW+LM7qZEJEsMNPrfC03APKmZsJgpWCDWOKZvkZcvjV
|
||||
uYkQ4omYCTX5ohy+knMjdOmdH9c7SpqEWBDC86fiNex+O0XOMEZSa8DA
|
||||
-----END CERTIFICATE-----
|
||||
31
pkg/cm509/testchain_a02.crt
Normal file
31
pkg/cm509/testchain_a02.crt
Normal file
@@ -0,0 +1,31 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFYDCCBEigAwIBAgIQQAF3ITfU6UK47naqPGQKtzANBgkqhkiG9w0BAQsFADA/
|
||||
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
|
||||
DkRTVCBSb290IENBIFgzMB4XDTIxMDEyMDE5MTQwM1oXDTI0MDkzMDE4MTQwM1ow
|
||||
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
|
||||
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwggIiMA0GCSqGSIb3DQEB
|
||||
AQUAA4ICDwAwggIKAoICAQCt6CRz9BQ385ueK1coHIe+3LffOJCMbjzmV6B493XC
|
||||
ov71am72AE8o295ohmxEk7axY/0UEmu/H9LqMZshftEzPLpI9d1537O4/xLxIZpL
|
||||
wYqGcWlKZmZsj348cL+tKSIG8+TA5oCu4kuPt5l+lAOf00eXfJlII1PoOK5PCm+D
|
||||
LtFJV4yAdLbaL9A4jXsDcCEbdfIwPPqPrt3aY6vrFk/CjhFLfs8L6P+1dy70sntK
|
||||
4EwSJQxwjQMpoOFTJOwT2e4ZvxCzSow/iaNhUd6shweU9GNx7C7ib1uYgeGJXDR5
|
||||
bHbvO5BieebbpJovJsXQEOEO3tkQjhb7t/eo98flAgeYjzYIlefiN5YNNnWe+w5y
|
||||
sR2bvAP5SQXYgd0FtCrWQemsAXaVCg/Y39W9Eh81LygXbNKYwagJZHduRze6zqxZ
|
||||
Xmidf3LWicUGQSk+WT7dJvUkyRGnWqNMQB9GoZm1pzpRboY7nn1ypxIFeFntPlF4
|
||||
FQsDj43QLwWyPntKHEtzBRL8xurgUBN8Q5N0s8p0544fAQjQMNRbcTa0B7rBMDBc
|
||||
SLeCO5imfWCKoqMpgsy6vYMEG6KDA0Gh1gXxG8K28Kh8hjtGqEgqiNx2mna/H2ql
|
||||
PRmP6zjzZN7IKw0KKP/32+IVQtQi0Cdd4Xn+GOdwiK1O5tmLOsbdJ1Fu/7xk9TND
|
||||
TwIDAQABo4IBRjCCAUIwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw
|
||||
SwYIKwYBBQUHAQEEPzA9MDsGCCsGAQUFBzAChi9odHRwOi8vYXBwcy5pZGVudHJ1
|
||||
c3QuY29tL3Jvb3RzL2RzdHJvb3RjYXgzLnA3YzAfBgNVHSMEGDAWgBTEp7Gkeyxx
|
||||
+tvhS5B1/8QVYIWJEDBUBgNVHSAETTBLMAgGBmeBDAECATA/BgsrBgEEAYLfEwEB
|
||||
ATAwMC4GCCsGAQUFBwIBFiJodHRwOi8vY3BzLnJvb3QteDEubGV0c2VuY3J5cHQu
|
||||
b3JnMDwGA1UdHwQ1MDMwMaAvoC2GK2h0dHA6Ly9jcmwuaWRlbnRydXN0LmNvbS9E
|
||||
U1RST09UQ0FYM0NSTC5jcmwwHQYDVR0OBBYEFHm0WeZ7tuXkAXOACIjIGlj26Ztu
|
||||
MA0GCSqGSIb3DQEBCwUAA4IBAQAKcwBslm7/DlLQrt2M51oGrS+o44+/yQoDFVDC
|
||||
5WxCu2+b9LRPwkSICHXM6webFGJueN7sJ7o5XPWioW5WlHAQU7G75K/QosMrAdSW
|
||||
9MUgNTP52GE24HGNtLi1qoJFlcDyqSMo59ahy2cI2qBDLKobkx/J3vWraV0T9VuG
|
||||
WCLKTVXkcGdtwlfFRjlBz4pYg1htmf5X6DYO8A4jqv2Il9DjXA6USbW1FzXSLr9O
|
||||
he8Y4IWS6wY7bCkjCWDcRQJMEhg76fsO3txE+FiYruq9RUWhiF1myv4Q6W+CyBFC
|
||||
Dfvp7OOGAN6dEOM4+qR9sdjoSYKEBpsr6GtPAQw4dy753ec5
|
||||
-----END CERTIFICATE-----
|
||||
31
pkg/cm509/testchain_a03.crt
Normal file
31
pkg/cm509/testchain_a03.crt
Normal file
@@ -0,0 +1,31 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFVDCCBDygAwIBAgIRAKLBiJX85huxZJB/Ylc2Y5gwDQYJKoZIhvcNAQEFBQAw
|
||||
gakxCzAJBgNVBAYTAnVzMQ0wCwYDVQQIEwRVdGFoMRcwFQYDVQQHEw5TYWx0IExh
|
||||
a2UgQ2l0eTEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMREw
|
||||
DwYDVQQLEwhEU1RDQSBYMTEWMBQGA1UEAxMNRFNUIFJvb3RDQSBYMTEhMB8GCSqG
|
||||
SIb3DQEJARYSY2FAZGlnc2lndHJ1c3QuY29tMB4XDTA0MDkwODE0NDM0NVoXDTA4
|
||||
MTEyODEzMDI1OVowPzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3Qg
|
||||
Q28uMRcwFQYDVQQDEw5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQAD
|
||||
ggEPADCCAQoCggEBAN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+Do
|
||||
M3ZJKuM/IUmTrE4Orz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwG
|
||||
MoOifooUMM0RoOEqOLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOe
|
||||
DNoJjj4XLh7dIN9bxiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqc
|
||||
kh49ZLOMxt+/yUFw7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr
|
||||
2m7xPi71XAicPNaDaeQQmxkqtilX4+U9m5/wAl0CAwEAAaOCAd4wggHaMA8GA1Ud
|
||||
EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMIG7BgNVHR8EgbMwgbAwga2ggaqg
|
||||
gaeGgaRsZGFwOi8vbGRhcC5kaWdzaWd0cnVzdC5jb20vY249RFNUJTIwUm9vdENB
|
||||
JTIwWDEsb3U9RFNUQ0ElMjBYMSxvPURpZ2l0YWwlMjBTaWduYXR1cmUlMjBUcnVz
|
||||
dCUyMENvLixsPVNhbHQlMjBMYWtlJTIwQ2l0eSxTPVV0YWgsYz11cz9jZXJ0aWZp
|
||||
Y2F0ZVJldm9jYXRpb25MaXN0O2JpbmFyeTCBuAYIKwYBBQUHAQEEgaswgagwgaUG
|
||||
CCsGAQUFBzAChoGYbGRhcDovL2xkYXAuZGlnc2lndHJ1c3QuY29tL2NuPURTVCUy
|
||||
MFJvb3RDQSUyMFgxLG91PURTVENBJTIwWDEsbz1EaWdpdGFsJTIwU2lnbmF0dXJl
|
||||
JTIwVHJ1c3QlMjBDby4sbD1TYWx0JTIwTGFrZSUyMENpdHksUz1VdGFoLGM9dXM/
|
||||
Y0FDZXJ0aWZpY2F0ZTtiaW5hcnkwHwYDVR0jBBgwFoAUaU2asPSCd8A2GzVVCRQa
|
||||
/goSAAowHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqGSIb3DQEB
|
||||
BQUAA4IBAQCpFXMtsChLFvN/Z+mwiodooamIW0qjMoVGHeN9CcDdUIGQI7cgbT10
|
||||
tsJuEZx3opp2s4LoM7Gn/o0T/rysLlT34vPwI4Ei/df3aG0ite5ehqWgMuc65n1P
|
||||
tadwl5JFFx3l8B0YWrOv5xJ0kY+br4FGI2OGqxagBtH2y7Uak4Iq2xipTHhlvx6a
|
||||
DWAzGQHovRdLf1c4cFti11gU29QYPgDXsJSuriq3xcItGzjYZT9V45WiIlmdvez0
|
||||
vCr6wcnjifctVfQ7z2o2+yl7A1+ijNhDhyfcrdPqctwx0Nk8IDitss+vNMsqoEHx
|
||||
uBoIoQw0DQhKAEYri9bw+9wqZhotOjMw
|
||||
-----END CERTIFICATE-----
|
||||
460
pkg/cm509/x509.go
Normal file
460
pkg/cm509/x509.go
Normal file
@@ -0,0 +1,460 @@
|
||||
package cm509
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/base64"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"net"
|
||||
"time"
|
||||
)
|
||||
|
||||
type CreateIssuerPairParams struct {
|
||||
CommonName string
|
||||
SignerCert string
|
||||
SignerKey string
|
||||
}
|
||||
type CreateIssuerPairResult struct {
|
||||
Name string
|
||||
Cert string
|
||||
Key string
|
||||
}
|
||||
|
||||
|
||||
func CreateIssuerPair(params *CreateIssuerPairParams) (*CreateIssuerPairResult, error) {
|
||||
var err error
|
||||
res := &CreateIssuerPairResult{}
|
||||
|
||||
if params.SignerKey != "" && params.SignerCert == "" {
|
||||
err = fmt.Errorf("The signature key and certificate must be defined together")
|
||||
return res, err
|
||||
}
|
||||
if params.SignerKey == "" && params.SignerCert != "" {
|
||||
err = fmt.Errorf("The signature key and certificate must be defined together")
|
||||
return res, err
|
||||
}
|
||||
|
||||
var signerKey any
|
||||
if params.SignerKey != "" {
|
||||
signerKey, err = ParseDoubleEncodedKey(params.SignerKey)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
}
|
||||
var signerCert *x509.Certificate
|
||||
if params.SignerCert != "" {
|
||||
signerCert, err = ParseDoubleEncodedCerificate(params.SignerCert)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
}
|
||||
|
||||
certPem := make([]byte, 0)
|
||||
keyPem := make([]byte, 0)
|
||||
|
||||
now := time.Now()
|
||||
|
||||
const yearsAfter int = 10
|
||||
const keySize int = 2048
|
||||
|
||||
certKey, err := rsa.GenerateKey(rand.Reader, keySize)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("Can't create a private key: %v", err)
|
||||
return res, err
|
||||
|
||||
}
|
||||
keyPemBlock := &pem.Block{
|
||||
Type: "RSA PRIVATE KEY",
|
||||
Bytes: x509.MarshalPKCS1PrivateKey(certKey),
|
||||
}
|
||||
keyPem = pem.EncodeToMemory(keyPemBlock)
|
||||
|
||||
certSubject := pkix.Name{
|
||||
CommonName: params.CommonName,
|
||||
}
|
||||
|
||||
certIssuer := certSubject
|
||||
if signerCert != nil {
|
||||
certIssuer = signerCert.Subject
|
||||
}
|
||||
|
||||
var issuerKey any = certKey
|
||||
if signerKey != nil {
|
||||
issuerKey = signerKey
|
||||
}
|
||||
|
||||
res.Name = certSubject.String()
|
||||
|
||||
certTempl := &x509.Certificate{
|
||||
SerialNumber: big.NewInt(now.Unix()),
|
||||
NotBefore: now,
|
||||
NotAfter: now.AddDate(yearsAfter, 0, 0),
|
||||
Subject: certSubject,
|
||||
Issuer: certIssuer,
|
||||
IsCA: true,
|
||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
|
||||
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
|
||||
BasicConstraintsValid: true,
|
||||
}
|
||||
|
||||
parentCert := certTempl
|
||||
if signerCert != nil {
|
||||
parentCert = signerCert
|
||||
}
|
||||
|
||||
certBytes, err := x509.CreateCertificate(rand.Reader, certTempl, parentCert, &certKey.PublicKey, issuerKey)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("Can't create a certificate: %v", err)
|
||||
return res, err
|
||||
|
||||
}
|
||||
certPemBlock := pem.Block{
|
||||
Type: "CERTIFICATE",
|
||||
Bytes: certBytes,
|
||||
}
|
||||
certPem = pem.EncodeToMemory(&certPemBlock)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
res.Cert = base64.StdEncoding.EncodeToString(certPem)
|
||||
res.Key = base64.StdEncoding.EncodeToString(keyPem)
|
||||
return res, err
|
||||
}
|
||||
|
||||
|
||||
|
||||
func CreateIssuerPairV0(params *CreateIssuerPairParams) (*CreateIssuerPairResult, error) {
|
||||
var err error
|
||||
res := &CreateIssuerPairResult{}
|
||||
|
||||
certPem := make([]byte, 0)
|
||||
keyPem := make([]byte, 0)
|
||||
|
||||
now := time.Now()
|
||||
|
||||
const yearsAfter int = 10
|
||||
const keySize int = 2048
|
||||
|
||||
key, err := rsa.GenerateKey(rand.Reader, keySize)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("Can't create a private key: %v", err)
|
||||
return res, err
|
||||
|
||||
}
|
||||
keyPemBlock := pem.Block{
|
||||
Type: "RSA PRIVATE KEY",
|
||||
Bytes: x509.MarshalPKCS1PrivateKey(key),
|
||||
}
|
||||
keyPem = pem.EncodeToMemory(&keyPemBlock)
|
||||
|
||||
subjectName := pkix.Name{
|
||||
CommonName: params.CommonName,
|
||||
}
|
||||
issuerName := subjectName
|
||||
res.Name = subjectName.String()
|
||||
|
||||
certTempl := x509.Certificate{
|
||||
SerialNumber: big.NewInt(now.Unix()),
|
||||
NotBefore: now,
|
||||
NotAfter: now.AddDate(yearsAfter, 0, 0),
|
||||
Subject: subjectName,
|
||||
Issuer: issuerName,
|
||||
IsCA: true,
|
||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
|
||||
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
|
||||
BasicConstraintsValid: true,
|
||||
}
|
||||
certBytes, err := x509.CreateCertificate(rand.Reader, &certTempl, &certTempl, &key.PublicKey, key)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("Can't create a certificate: %v", err)
|
||||
return res, err
|
||||
|
||||
}
|
||||
certPemBlock := pem.Block{
|
||||
Type: "CERTIFICATE",
|
||||
Bytes: certBytes,
|
||||
}
|
||||
certPem = pem.EncodeToMemory(&certPemBlock)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
res.Cert = base64.StdEncoding.EncodeToString(certPem)
|
||||
res.Key = base64.StdEncoding.EncodeToString(keyPem)
|
||||
return res, err
|
||||
}
|
||||
|
||||
type CreateServicePairParams struct {
|
||||
CommonName string
|
||||
DNSNames []string
|
||||
IPAddresses []string
|
||||
IssuerKey string
|
||||
IssuerCert string
|
||||
}
|
||||
type CreateServicePairResult struct {
|
||||
Name string
|
||||
Cert string
|
||||
Key string
|
||||
}
|
||||
|
||||
func CreateServicePairV2(params *CreateServicePairParams) (*CreateServicePairResult, error) {
|
||||
var err error
|
||||
|
||||
res := &CreateServicePairResult{}
|
||||
certPem := make([]byte, 0)
|
||||
keyPem := make([]byte, 0)
|
||||
now := time.Now()
|
||||
|
||||
const yearsAfter int = 10
|
||||
const keySize int = 2048
|
||||
|
||||
key, err := rsa.GenerateKey(rand.Reader, keySize)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("Can't create a private key: %v", err)
|
||||
return res, err
|
||||
}
|
||||
keyPemBlock := pem.Block{
|
||||
Type: "RSA PRIVATE KEY",
|
||||
Bytes: x509.MarshalPKCS1PrivateKey(key),
|
||||
}
|
||||
keyPem = pem.EncodeToMemory(&keyPemBlock)
|
||||
|
||||
caKeyPem, err := base64.StdEncoding.DecodeString(params.IssuerKey)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
pemBlock, _ := pem.Decode(caKeyPem)
|
||||
if pemBlock == nil {
|
||||
err := fmt.Errorf("Can't parse a CA private key block")
|
||||
return res, err
|
||||
}
|
||||
caKey, err := x509.ParsePKCS1PrivateKey(pemBlock.Bytes)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("Can't parse a CA private key")
|
||||
return res, err
|
||||
}
|
||||
|
||||
netAddresses := make([]net.IP, 0)
|
||||
for _, ipAddress := range params.IPAddresses {
|
||||
netAddress := net.ParseIP(ipAddress)
|
||||
netAddresses = append(netAddresses, netAddress)
|
||||
}
|
||||
certTempl := x509.Certificate{
|
||||
SerialNumber: big.NewInt(now.Unix()),
|
||||
NotBefore: now,
|
||||
NotAfter: now.AddDate(yearsAfter, 0, 0),
|
||||
Subject: pkix.Name{
|
||||
CommonName: params.CommonName,
|
||||
},
|
||||
DNSNames: params.DNSNames,
|
||||
IPAddresses: netAddresses,
|
||||
IsCA: false,
|
||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
|
||||
KeyUsage: x509.KeyUsageDigitalSignature,
|
||||
BasicConstraintsValid: true,
|
||||
}
|
||||
certBytes, err := x509.CreateCertificate(rand.Reader, &certTempl, &certTempl, &key.PublicKey, caKey)
|
||||
if err != nil {
|
||||
return res, fmt.Errorf("Can't create a certificate: %v", err)
|
||||
|
||||
}
|
||||
certPemBlock := pem.Block{
|
||||
Type: "CERTIFICATE",
|
||||
Bytes: certBytes,
|
||||
}
|
||||
|
||||
certPem = pem.EncodeToMemory(&certPemBlock)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
res.Cert = base64.StdEncoding.EncodeToString(certPem)
|
||||
res.Key = base64.StdEncoding.EncodeToString(keyPem)
|
||||
return res, err
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
func ParseDoubleEncodedCerificate(certString string) (*x509.Certificate, error) {
|
||||
var err error
|
||||
res := &x509.Certificate{}
|
||||
|
||||
certPEM, err := base64.StdEncoding.DecodeString(certString)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("Failed to parse base64 certificate string: %v", err)
|
||||
return res, err
|
||||
}
|
||||
certBlock, _ := pem.Decode([]byte(certPEM))
|
||||
if certBlock == nil {
|
||||
err := fmt.Errorf("Failed to parse certificate PEM")
|
||||
return res, err
|
||||
}
|
||||
if certBlock.Type != "CERTIFICATE" {
|
||||
err := fmt.Errorf("Unknown PEM certificate type: %s", certBlock.Type)
|
||||
return res, err
|
||||
}
|
||||
if len(certBlock.Bytes) == 0 {
|
||||
err := fmt.Errorf("Empty PEM certificate block")
|
||||
return res, err
|
||||
}
|
||||
|
||||
res, err = x509.ParseCertificate(certBlock.Bytes)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
func ParseEncodedCerificate(certPEM string) (*x509.Certificate, error) {
|
||||
var err error
|
||||
res := &x509.Certificate{}
|
||||
|
||||
certBlock, _ := pem.Decode([]byte(certPEM))
|
||||
if certBlock == nil {
|
||||
err := fmt.Errorf("Failed to parse certificate PEM")
|
||||
return res, err
|
||||
}
|
||||
if certBlock.Type != "CERTIFICATE" {
|
||||
err := fmt.Errorf("Unknown PEM certificate type: %s", certBlock.Type)
|
||||
return res, err
|
||||
}
|
||||
if len(certBlock.Bytes) == 0 {
|
||||
err := fmt.Errorf("Empty PEM certificate block")
|
||||
return res, err
|
||||
}
|
||||
res, err = x509.ParseCertificate(certBlock.Bytes)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
func ParseDoubleEncodedKey(keyString string) (any, error) {
|
||||
var err error
|
||||
var res any
|
||||
|
||||
keyPEM, err := base64.StdEncoding.DecodeString(keyString)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("Failed to parse base64 key string: %v", err)
|
||||
return res, err
|
||||
}
|
||||
keyBlock, _ := pem.Decode([]byte(keyPEM))
|
||||
if keyBlock == nil {
|
||||
err := fmt.Errorf("Failed to parse key PEM")
|
||||
return res, err
|
||||
}
|
||||
switch keyBlock.Type {
|
||||
case "PRIVATE KEY":
|
||||
res, err = x509.ParsePKCS8PrivateKey(keyBlock.Bytes)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
case "RSA PRIVATE KEY":
|
||||
res, err = x509.ParsePKCS1PrivateKey(keyBlock.Bytes)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
case "EC PRIVATE KEY":
|
||||
res, err = x509.ParseECPrivateKey(keyBlock.Bytes)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
default:
|
||||
err := fmt.Errorf("Unknown PEM key type: %s", keyBlock.Type)
|
||||
return res, err
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
func ParseEncodedKey(keyPEM string) (any, error) {
|
||||
var err error
|
||||
var res any
|
||||
|
||||
keyBlock, _ := pem.Decode([]byte(keyPEM))
|
||||
if keyBlock == nil {
|
||||
err := fmt.Errorf("Failed to parse key PEM")
|
||||
return res, err
|
||||
}
|
||||
switch keyBlock.Type {
|
||||
case "PRIVATE KEY":
|
||||
res, err = x509.ParsePKCS8PrivateKey(keyBlock.Bytes)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
case "RSA PRIVATE KEY":
|
||||
res, err = x509.ParsePKCS1PrivateKey(keyBlock.Bytes)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
case "EC PRIVATE KEY":
|
||||
res, err = x509.ParseECPrivateKey(keyBlock.Bytes)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
default:
|
||||
err := fmt.Errorf("Unknown PEM key type: %s", keyBlock.Type)
|
||||
return res, err
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
func CheckDoubleEncodedCertificateChain(topIssuerCN string, certStrings []string) ([]string, error) {
|
||||
var err error
|
||||
res := make([]string, 0)
|
||||
|
||||
certObjs := make([]*x509.Certificate, 0)
|
||||
for _, certString := range certStrings {
|
||||
certObj, err := ParseDoubleEncodedCerificate(certString)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
certObjs = append(certObjs, certObj)
|
||||
}
|
||||
|
||||
issuerFound := false
|
||||
issuerIndex := -1
|
||||
for i, certObj := range certObjs {
|
||||
if topIssuerCN == certObj.Subject.String() {
|
||||
issuerIndex = i
|
||||
issuerFound = true
|
||||
}
|
||||
}
|
||||
if !issuerFound {
|
||||
err := fmt.Errorf("Issuer for %s cannot found", topIssuerCN)
|
||||
return res, err
|
||||
}
|
||||
interCertObj := certObjs[issuerIndex]
|
||||
interCertString := certStrings[issuerIndex]
|
||||
if !interCertObj.IsCA {
|
||||
err := fmt.Errorf("Issuer %s is not CA", interCertObj.Subject.String())
|
||||
return res, err
|
||||
}
|
||||
expired := interCertObj.NotAfter.Before(time.Now())
|
||||
if !expired {
|
||||
err := fmt.Errorf("Issuer %s expired %v", interCertObj.Subject.String(), interCertObj.NotAfter)
|
||||
return res, err
|
||||
}
|
||||
|
||||
res = append(res, interCertString)
|
||||
if interCertObj.Subject.String() == interCertObj.Issuer.String() {
|
||||
return res, err
|
||||
}
|
||||
updatedCertStrings := append(certStrings[:issuerIndex], certStrings[issuerIndex+1:]...)
|
||||
topIssuerCN = interCertObj.Issuer.String()
|
||||
|
||||
certStringsTail, err := CheckDoubleEncodedCertificateChain(topIssuerCN, updatedCertStrings)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
res = append(res, certStringsTail...)
|
||||
return res, err
|
||||
}
|
||||
48
pkg/cm509/x509_test.go
Normal file
48
pkg/cm509/x509_test.go
Normal file
@@ -0,0 +1,48 @@
|
||||
package cm509
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"sigs.k8s.io/yaml"
|
||||
)
|
||||
|
||||
func TestCertChainCheckerErr(t *testing.T) {
|
||||
var err error
|
||||
|
||||
certBytes, err := os.ReadFile("testchain_a01.crt")
|
||||
require.NoError(t, err)
|
||||
require.NotZero(t, len(certBytes))
|
||||
certObj, err := ParseEncodedCerificate(string(certBytes))
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, certObj)
|
||||
|
||||
certStrings := make([]string, 0)
|
||||
for i := 1; i < 4; i++ {
|
||||
certBytes, err := os.ReadFile(fmt.Sprintf("testchain_a%02d.crt", i))
|
||||
require.NoError(t, err)
|
||||
require.NotZero(t, len(certBytes))
|
||||
certString := base64.StdEncoding.EncodeToString(certBytes)
|
||||
certStrings = append(certStrings, certString)
|
||||
}
|
||||
topIssuerCN := certObj.Issuer.String()
|
||||
|
||||
_, err = CheckDoubleEncodedCertificateChain(topIssuerCN, certStrings)
|
||||
require.Error(t, err)
|
||||
//require.NotNil(t, resString)
|
||||
//require.NotZero(t, len(resString))
|
||||
}
|
||||
|
||||
func printObj(label string, obj any) {
|
||||
objBytes, _ := yaml.Marshal(obj)
|
||||
objString := string(objBytes)
|
||||
if strings.Count(objString, "\n") < 2 {
|
||||
fmt.Printf("==== %s: %s\n", label, objString)
|
||||
} else {
|
||||
fmt.Printf("==== %s ::\n%s\n", label, objString)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user