How to parse IDP extension information in a CRL using Go

58 views
Skip to first unread message

Qianxin Cheng

unread,
Apr 3, 2025, 1:46:25 PM4/3/25
to golang-nuts
Developer, I wrote some code in Go to parse the IDP extension information in a CRL, but I'm encountering an error while parsing the DistributionPoint. I've tried multiple times, but I can't get it to work. Can you help me figure out what is wrong with this code?
package main

import (
"crypto/x509"
"crypto/x509/pkix"
"encoding/asn1"
"flag"
"fmt"
"os"
)

type IssuingDistributionPoint struct {
DistributionPoint        asn1.RawValue `asn1:"optional,tag:0,explicit"`
OnlyContainsUserCerts    bool          `asn1:"optional,tag:1"`
OnlyContainsCACerts      bool          `asn1:"optional,tag:2"`
OnlySomeReasons          asn1.BitString `asn1:"optional,tag:3"`
IndirectCRL              bool          `asn1:"optional,tag:4"`
OnlyContainsAttributeCerts bool        `asn1:"optional,tag:5"`
}

type GeneralNames []asn1.RawValue

func main() {
// 1. Command line flag processing
crlFilePath := flag.String("crl", "", "CRL file path")
flag.Parse()

if *crlFilePath == "" {
fmt.Println("CRL file path is required")
os.Exit(1)
}

// 2. File reading
derBytes, err := os.ReadFile(*crlFilePath)
if err != nil {
fmt.Printf("Unable to read file: %v\n", err)
os.Exit(1)
}

// 3. CRL parsing
crl, err := x509.ParseRevocationList(derBytes)
if err != nil {
fmt.Printf("CRL parsing failed: %v\n", err)
os.Exit(1)
}

oidIssuingDistributionPoint := asn1.ObjectIdentifier{2, 5, 29, 28}

// 4. Process extensions of the CRL
for _, ext := range crl.Extensions {
if ext.Id.Equal(oidIssuingDistributionPoint) {
var idp IssuingDistributionPoint
if _, err := asn1.Unmarshal(ext.Value, &idp); err != nil {
fmt.Printf("Unable to decode IDP extension: %v\n", err)
continue
}

// 5. Print IDP flags
fmt.Printf("IDP Extension Flags:\n")
fmt.Printf(" OnlyContainsUserCerts: %t\n", idp.OnlyContainsUserCerts)
fmt.Printf(" OnlyContainsCACerts: %t\n", idp.OnlyContainsCACerts)
fmt.Printf(" IndirectCRL: %t\n", idp.IndirectCRL)

// 6.
if len(idp.DistributionPoint.Bytes) > 0 {
// Unpack outer explicit tag
var explicitTag struct {
Raw asn1.RawContent `asn1:"tag:0,explicit"`
}
if _, err := asn1.Unmarshal(idp.DistributionPoint.Bytes, &explicitTag); err != nil {
fmt.Printf("Failed to unpack explicit tag: %v\n", err)
continue
}

// Parse GeneralNames
var generalNames GeneralNames
if _, err := asn1.Unmarshal(explicitTag.Raw, &generalNames); err != nil {
fmt.Printf("Unable to parse GeneralNames: %v\n", err)
continue
}

// 7. Process URI and DirectoryName
for _, rawGN := range generalNames {
switch rawGN.Tag {
case 6: // URI
var uri string
if _, err := asn1.Unmarshal(rawGN.Bytes, &uri); err != nil {
fmt.Printf("Failed to parse URI: %v\n", err)
continue
}
fmt.Printf(" URI: %s\n", uri)

case 4: // DirectoryName
var rdnSeq pkix.RDNSequence
if _, err := asn1.Unmarshal(rawGN.Bytes, &rdnSeq); err != nil {
fmt.Printf("Failed to parse DirectoryName: %v\n", err)
continue
}
var name pkix.Name
name.FillFromRDNSequence(&rdnSeq)
fmt.Printf(" DirectoryName: %s\n", name.String())
}
}
}
}
}
}
crl_IDP_Normal.der
Reply all
Reply to author
Forward
0 new messages