Skip to content

Commit

Permalink
parse certs
Browse files Browse the repository at this point in the history
  • Loading branch information
shreyav committed Mar 20, 2024
1 parent d922229 commit b268d45
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 0 deletions.
41 changes: 41 additions & 0 deletions uma/test/uma_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/uma-universal-money-address/uma-go-sdk/uma"
umaprotocol "github.com/uma-universal-money-address/uma-go-sdk/uma/protocol"
"github.com/uma-universal-money-address/uma-go-sdk/uma/utils"
"math"
"net/url"
"strconv"
Expand Down Expand Up @@ -673,6 +674,46 @@ func TestParseAndEncodePayReqToQueryParams(t *testing.T) {
require.Equal(t, payreq, payreqReparsed)
}

func TestParseX509CertificateString(t *testing.T) {
pemCert := `
-----BEGIN CERTIFICATE-----
MIIB1zCCAXygAwIBAgIUGN3ihBj1RnKoeTM/auDFnNoThR4wCgYIKoZIzj0EAwIw
QjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCmNhbGlmb3JuaWExDjAMBgNVBAcMBWxv
cyBhMQ4wDAYDVQQKDAVsaWdodDAeFw0yNDAzMDUyMTAzMTJaFw0yNDAzMTkyMTAz
MTJaMEIxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApjYWxpZm9ybmlhMQ4wDAYDVQQH
DAVsb3MgYTEOMAwGA1UECgwFbGlnaHQwVjAQBgcqhkjOPQIBBgUrgQQACgNCAARB
nFRn6lY/ABD9YU+F6IWsmcIbjo1BYkEXX91e/SJE/pB+Lm+j3WYxsbF80oeY2o2I
KjTEd21EzECQeBx6reobo1MwUTAdBgNVHQ4EFgQUU87LnQdiP6XIE6LoKU1PZnbt
bMwwHwYDVR0jBBgwFoAUU87LnQdiP6XIE6LoKU1PZnbtbMwwDwYDVR0TAQH/BAUw
AwEB/zAKBggqhkjOPQQDAgNJADBGAiEAvsrvoeo3rbgZdTHxEUIgP0ArLyiO34oz
NlwL4gk5GpgCIQCvRx4PAyXNV9T6RRE+3wFlqwluOc/pPOjgdRw/wpoNPQ==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIICdjCCAV6gAwIBAgIUAekCcU1Qhjo2Y6L2Down9BLdfdUwDQYJKoZIhvcNAQEL
BQAwNDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAmNhMQwwCgYDVQQHDANsb3MxCjAI
BgNVBAoMAWEwHhcNMjQwMzA4MDEwNTU3WhcNMjUwMzA4MDEwNTU3WjBAMQswCQYD
VQQGEwJVUzELMAkGA1UECAwCY2ExDDAKBgNVBAcMA2xvczEKMAgGA1UECgwBYTEK
MAgGA1UECwwBYTBWMBAGByqGSM49AgEGBSuBBAAKA0IABJ11ZAQKylgIzZmuI5NE
+DyZ9BUDZhxUPSxTxl+s1am+Lxzr9D7wlwOiiqCYHFWpL6lkCmJcCC06P3RyzXIT
KmyjQjBAMB0GA1UdDgQWBBRXgW6xGB3+mTSSUKlhSiu3LS+TKTAfBgNVHSMEGDAW
gBTFmyv7+YDpK0WAOHJYAzjynmWsMDANBgkqhkiG9w0BAQsFAAOCAQEAFVAA3wo+
Hi/k+OWO/1CFqIRV/0cA8F05sBMiKVA11xB6I1y54aUV4R0jN76fOiN1jnZqTRnM
G8rZUfQgE/LPVbb1ERHQfd8yaeI+TerKdPkMseu/jnvI+dDJfQdsY7iaa7NPO0dm
t8Nz75cYW8kYuDaq0Hb6uGsywf9LGO/VjrDhyiRxmZ1Oq4JxQmLuh5SDcPfqHTR3
VbMC1b7eVXaA9O2qYS36zv8cCUSUl5sOSwM6moaFN+xLtVNJ6ZhKPNS2Gd8znhzZ
AQZcDDpXBO6ORNbhVk5A3X6eQX4Ek1HBTa3pcSUQomYAA9TIuVzL6DSot5GWS8Ek
usLY8crt6ys3KQ==
-----END CERTIFICATE-----
`
pubkey, err := utils.ExtractPubkeyFromPemCertificateChain(pemCert)
require.NoError(t, err)

publicKeyBytes := pubkey.SerializeUncompressed()
expectedPublicKey, err := hex.DecodeString("04419c5467ea563f0010fd614f85e885ac99c21b8e8d416241175fdd5efd2244fe907e2e6fa3dd6631b1b17cd28798da8d882a34c4776d44cc4090781c7aadea1b")
require.NoError(t, err)
require.Equal(t, publicKeyBytes, expectedPublicKey)
}

func createLnurlpRequest(t *testing.T, signingPrivateKey []byte) umaprotocol.LnurlpRequest {
queryUrl, err := uma.GetSignedLnurlpRequestUrl(signingPrivateKey, "[email protected]", "vasp1.com", true, nil)
require.NoError(t, err)
Expand Down
72 changes: 72 additions & 0 deletions uma/utils/cert_utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package utils

import (
"crypto/x509/pkix"
"encoding/asn1"
"encoding/pem"
"errors"
"github.com/decred/dcrd/dcrec/secp256k1/v4"
"math/big"
"time"
)

func ExtractPubkeyFromPemCertificateChain(certChain string) (*secp256k1.PublicKey, error) {
block, _ := pem.Decode([]byte(certChain))
if block == nil {
return nil, errors.New("failed to parse certificate chain PEM")
}
asn1Data := block.Bytes

var v []*certificate
for len(asn1Data) > 0 {
cert := new(certificate)
var err error
asn1Data, err = asn1.Unmarshal(asn1Data, cert)
if err != nil {
return nil, err
}
v = append(v, cert)
}

if len(v) == 0 {
return nil, errors.New("empty certificate chain")
}

return parseToSec256K1PublicKey(&v[0].TBSCertificate.PublicKey)
}

func parseToSec256K1PublicKey(keyData *publicKeyInfo) (*secp256k1.PublicKey, error) {
asn1Data := keyData.PublicKey.RightAlign()
return secp256k1.ParsePubKey(asn1Data)
}

type certificate struct {
Raw asn1.RawContent
TBSCertificate tbsCertificate
SignatureAlgorithm pkix.AlgorithmIdentifier
SignatureValue asn1.BitString
}

type tbsCertificate struct {
Raw asn1.RawContent
Version int `asn1:"optional,explicit,default:0,tag:0"`
SerialNumber *big.Int
SignatureAlgorithm pkix.AlgorithmIdentifier
Issuer asn1.RawValue
Validity validity
Subject asn1.RawValue
PublicKey publicKeyInfo
UniqueId asn1.BitString `asn1:"optional,tag:1"`
SubjectUniqueId asn1.BitString `asn1:"optional,tag:2"`
Extensions []pkix.Extension `asn1:"optional,explicit,tag:3"`
}

type publicKeyInfo struct {
Raw asn1.RawContent
Algorithm pkix.AlgorithmIdentifier
PublicKey asn1.BitString
}

type validity struct {
NotBefore, NotAfter time.Time
}

0 comments on commit b268d45

Please sign in to comment.