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{}