I have been trying to connect to an LND node using Rust as a language. I have been constantly be given this error:
tonic::transport::Error(Transport, hyper::Error(Connect, Custom { kind: InvalidData, error: InvalidCertificate(Other(CaUsedAsEndEntity)) }))'
I decided to take a look and see how lncli (built in golang) does this I encountered this two functions:
NewClientTLSFromFile comes from google.golang.org/grpc/credentials
AppendCertsFromPEM comes from https://pkg.go.dev/crypto/x509
# certFile is just the route to the tls.cert provided by LND
func NewClientTLSFromFile(certFile, serverNameOverride string) (TransportCredentials, error) {
b, err := ioutil.ReadFile(certFile)
if err != nil {
return nil, err
}
cp := x509.NewCertPool()
if !cp.AppendCertsFromPEM(b) {
return nil, fmt.Errorf("credentials: failed to append certificates")
}
println("RootCAs: ", cp)
return NewTLS(&tls.Config{ServerName: serverNameOverride, RootCAs: cp}), nil
}
func (s *CertPool) AppendCertsFromPEM(pemCerts []byte) (ok bool) {
for len(pemCerts) > 0 {
var block *pem.Block
block, pemCerts = pem.Decode(pemCerts)
if block == nil {
break
}
if block.Type != "CERTIFICATE" || len(block.Headers) != 0 {
continue
}
certBytes := block.Bytes
cert, err := ParseCertificate(certBytes)
if err != nil {
continue
}
var lazyCert struct {
sync.Once
v *Certificate
}
s.addCertFunc(sha256.Sum224(cert.Raw), string(cert.RawSubject), func() (*Certificate, error) {
lazyCert.Do(func() {
// This can't fail, as the same bytes already parsed above.
lazyCert.v, _ = ParseCertificate(certBytes)
certBytes = nil
})
return lazyCert.v, nil
})
ok = true
}
return ok
}
I have been breaking my head on how to do this in RUST but I haven't been able figure it out. sorry if this is a bad explanation.