I am trying to make are tls cert for HTTPS server by golang x509 package
and i got this error
tls: failed to find any PEM data in certificate input
After some research, I create my Cert like this
func Generatecert() {
ca := &x509.Certificate{
SerialNumber: big.NewInt(2023),
Subject: pkix.Name{
Organization: []string{"Company"},
OrganizationalUnit: []string{"lol"},
Country: []string{"US"},
Province: []string{""},
Locality: []string{"NY"},
StreetAddress: []string{"No street"},
PostalCode: []string{"77777"},
},
NotBefore: time.Now(),
NotAfter: time.Now().AddDate(10, 0, 0),
SubjectKeyId: []byte{1, 2, 3, 4, 5},
BasicConstraintsValid: true,
IsCA: true,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
}
certpubl, certpriv, err := ed25519.GenerateKey(rand.Reader)
if err != nil {
log.Println("key generate failed", err)
return
}
certCert, err := x509.CreateCertificate(rand.Reader, ca, ca, certpubl, certpriv)
if err != nil {
log.Println("create cert failed", err)
return
}
out := &bytes.Buffer{}
//Encoding cert
certtestpem := &pem.Block{Type: "CERTIFICATE", Bytes: certCert}
pem.Encode(out, certtestpem)
publicCert := out.Bytes()
certDERBlock, publicCert := pem.Decode(publicCert)
//Check Decoded cert
print(certDERBlock.Type, "\n")
if publicCert != nil {
print("publicCert nil\n")
}
//Encoding Private Key
out.Reset()
privatepem, _ := x509.MarshalPKCS8PrivateKey(certpriv)
pem.Encode(out, &pem.Block{Type: "PRIVATE KEY", Bytes: privatepem})
privitKey := out.Bytes()
//check KeyPair
_, err = tls.X509KeyPair(publicCert, privitKey)
if err != nil {
print(err.Error())
}
}
it show the error like under
CERTIFICATE
publicCert nil
tls: failed to find any PEM data in certificate input
I try Decode after pem.EncodeToMemory
the pem.Type are correct, but variable "publicCert" is nil, And I try add are \n begin of the cert, it did nothing, but the cert itself is not nil, Can Somebody Help me with this
What sould I do to make a working Tls???
CodePudding user response:
after some debug, it seem like the pem.Encode function not working for me,
so i change it to pem.EncodeToMemory and it working thank you for the help.
CodePudding user response:
There are several problems in this code
publicCert := out.Bytes()
Checking the content of publicCert at this stage shows the expect value. But the following statement will simply overwrite publicCert:
certDERBlock, publicCert := pem.Decode(publicCert)
This can be seen by checking publicCert after this statement. As documented publicCert will now show the data after the actual certificate.
It should be instead
certDERBlock, _ := pem.Decode(publicCert)
Checking the content of publicCert after this corrected statement shows the expected value again.
out.Reset() privatepem, _ := x509.MarshalPKCS8PrivateKey(certpriv) pem.Encode(out, &pem.Block{Type: "PRIVATE KEY", Bytes: privatepem}) privitKey := out.Bytes()
This will get the expected value into privitKey. But, it will change publicCert since it is just a slice of out and out has been changed the the operations. Thus out will now contain at the beginning the privitKey and no longer the start of the certificate - and this is reflected in the value of publicCert.
See also the documentation for bytes.Buffer.Bytes
The slice is valid for use only until the next buffer modification (that is, only until the next call to a method like Read, Write, Reset, or Truncate)
So instead of just resetting the existing buffer
out.Reset()
it would be better to create a new buffer for privitKey and keep the existing one for publicCert
out = &bytes.Buffer{}
