FAQ
I find myself going in circles trying to pull OIDs from a certificate's
"X509v3 Extended Key Usage" (as `openssl x509 -in foo.pem -text` shows)
When I read in the cert:
cert, err := x509.ParseCertificate(block.Bytes)

the ExtKeyUsage, UnknownExtKeyUsage, nor PolicyIdentifiers contain the list
of extensions that I know are in the PEM certificate file.
Does anyone have a pointer on how to do this? or is it even available?

Take care,
vb

--

Search Discussions

  • Agl at Nov 7, 2012 at 11:19 pm

    On Wednesday, November 7, 2012 2:39:11 PM UTC-5, Vincent Batts wrote:

    the ExtKeyUsage, UnknownExtKeyUsage, nor PolicyIdentifiers contain the
    list of extensions that I know are in the PEM certificate file.
    Does anyone have a pointer on how to do this? or is it even available?
    crypto/x509 does not attempt to expose every possible cranny of a
    certificate and, if you have detailed parsing needs, you may need to use
    encoding/asn1 directly.

    Having said that, non-standard, extended key usages will be collected in
    UnknownExtKeyUsage. See line 749
    of http://golang.org/src/pkg/crypto/x509/x509.go.

    If you still aren't having any luck, please email me the PEM in question
    and I can take a look.


    Cheers

    AGL

    --
  • Vincent Batts at Nov 8, 2012 at 4:31 am

    On Wednesday, November 7, 2012 6:19:34 PM UTC-5, agl wrote:
    On Wednesday, November 7, 2012 2:39:11 PM UTC-5, Vincent Batts wrote:

    the ExtKeyUsage, UnknownExtKeyUsage, nor PolicyIdentifiers contain the
    list of extensions that I know are in the PEM certificate file.
    Does anyone have a pointer on how to do this? or is it even available?
    crypto/x509 does not attempt to expose every possible cranny of a
    certificate and, if you have detailed parsing needs, you may need to use
    encoding/asn1 directly.

    Having said that, non-standard, extended key usages will be collected in
    UnknownExtKeyUsage. See line 749 of
    http://golang.org/src/pkg/crypto/x509/x509.go.

    If you still aren't having any luck, please email me the PEM in question
    and I can take a look.


    Cheers

    AGL
    Good deal. At least there was not something completely obvious, that I was
    missing. Taking your direction, and ripping into the internal structs used
    in x509.go, I've made a route to marshal the extensions out of the
    RawTBSCertificate. I've put a mock example of such, inline below.
    I think it would be handy, to at have a method of *Certificate that would
    render these extensions though. :-)
    Thanks for the pointer.

    Take care,
    vb

    <<EXAMPLE

    package main

    import (
    "crypto/x509"
    "encoding/pem"
    "fmt"
    "io/ioutil"
    "os"

    "encoding/asn1"
    "math/big"
    "crypto/x509/pkix"
    "time"
    )


    var MyOID = asn1.ObjectIdentifier{5,5,5,5,5}

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

    type validity struct {
    NotBefore, NotAfter time.Time
    }

    type tbsCertificate struct {
    Raw asn1.RawContent
    Version int `asn1:"optional,explicit,default:1,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"`
    }

    func IsInMyOID(tomatch asn1.ObjectIdentifier) (bool) {
    return InOid(MyOID, tomatch)
    }

    func InOid(base asn1.ObjectIdentifier, tomatch asn1.ObjectIdentifier)
    (bool) {
    base_len := len(base)
    if (len(tomatch) < base_len) {
    return false
    }
    for i, _ := range base {
    if (base[i] != tomatch[i]) {
    return false
    }
    }
    return true
    }

    func main() {
    if (len(os.Args) == 1) {
    fmt.Println("ERROR: no pem certs provided")
    return
    }

    for _, file := range os.Args[1:] {
    pemCerts, err := ioutil.ReadFile(file)
    if (err != nil) {
    continue
    }
    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
    }

    cert, err := x509.ParseCertificate(block.Bytes)
    if err != nil {
    fmt.Println(err)
    continue
    }

    c := tbsCertificate{}
    rest, _ := asn1.Unmarshal(cert.RawTBSCertificate, &c)
    for _, ext := range c.Extensions {
    if (!ext.Critical && IsInMyOID(ext.Id)) {
    fmt.Printf("%T\n", ext.Id)
    fmt.Println(ext.Id)
    } else {
    fmt.Printf("NOT MINE: %d\n", ext.Id)
    }
    }
    if (len(rest) > 0) {
    fmt.Printf("rest, has %d left\n", len(rest))
    }
    }
    break
    }
    }

    EXAMPLE

    --

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedNov 7, '12 at 9:07p
activeNov 8, '12 at 4:31a
posts3
users2
websitegolang.org

2 users in discussion

Vincent Batts: 2 posts Agl: 1 post

People

Translate

site design / logo © 2021 Grokbase