parse output of exec.Command

106 views
Skip to first unread message

natxo....@gmail.com

unread,
Mar 27, 2025, 10:31:29 AM3/27/25
to golang-nuts
hi,

I am trying to parse he output of a command and not getting the desired results.

This is the sanitized output:

Certificate
       DN:             O=SUB,DOMAIN.TLD, CN=usernamej
       Serial:         333333
       Serialized id:  pkcs11:model=PKCS%2315%20emulated;token=1;manufacturer=piv_II;serial=xxxxxxxxxxxxxxxxxxxxxx;id=%08

Certificate
       DN:             O=OTHER.DOMAIN.TLD, CN=yetanother0.other.domain.tld
       Serial:         4444
       Serialized id:  pkcs11:model=PKCS%2315%20emulated;token=1;manufacturer=piv_II;serial=xxxxxxxxxxxxxxxxxxxx;id=%09


Skipping the part to run the command etc, that works:

ype ykcert struct {
DN           string
Serial       string
Serializedid string
}

certnr := 0
var certs = make(map[int]ykcert)
var certregex = regexp.MustCompile(`^Certificate`)
var dnregex = regexp.MustCompile(`\s+DN:\s+`)
var serialregex = regexp.MustCompile(`\s+Serial:`)
var serialidregex = regexp.MustCompile(`\s+Serialized id:`)
scanner := bufio.NewScanner(r)

go func() {
for scanner.Scan() {
if len(scanner.Text()) < 1 {
continue
}
switch {
case certregex.MatchString(scanner.Text()):
certnr++
case dnregex.MatchString(scanner.Text()):
certs[certnr] = ykcert{DN: scanner.Text()}
case serialregex.MatchString(scanner.Text()):
certs[certnr] = ykcert{Serial: scanner.Text()}
case serialidregex.MatchString(scanner.Text()):
certs[certnr] = ykcert{Serializedid: scanner.Text()}
}
}
done <- struct{}{}
}()

So I try to save the output in a map which is map[int]ykcert and while scanning the text if I match the desired regex, I assign that to the struct field.

What happens is that only the last case is 'remembered', so the map gets the correct number of elements, but the struct only gets filed with, in this case, the serializedid field. The other fields are not there.

How can I fill in the map elements fully?

Thanks for your input.

--
regards,
Natxo

natxo....@gmail.com

unread,
Mar 27, 2025, 11:02:14 AM3/27/25
to golang-nuts
obviously as soon as I post the question I think of the answer myself.

I need to use pointers.

Sorry for the noise, it's working now.

Jason E. Aten

unread,
Mar 27, 2025, 1:18:34 PM3/27/25
to golang-nuts
Hi Natxo,
You can also use "crypto/x509" x509.ParseCertificate() after pem.Decode() from "encoding/pem", if you
are only loading certificates and want a more rigorous way to determine the certificate's contents.
- Jason

natxo....@gmail.com

unread,
Mar 27, 2025, 1:58:18 PM3/27/25
to golang-nuts
hi Jason,

Thanks! Very nice code. In my use case the output is coming from openvpn cli (more precisely, openvpn --show-pkcs11-ids /path/to/opensc-pkcs11.so to get the a list of certificates on a smartcard, so not looking at the certificates themselves. I need to configure the config file for a vpn with the correct pkcs11 id to make life easier for colleagues when setting up a tunnel.

I use the x509 library as well, very handy.

I am not a programmer myself, and had forgotten how to use pointers :-)
Reply all
Reply to author
Forward
0 new messages