Skip to content

feat: integrate go-cryptoutil for extensible certificate parsing#335

Merged
masv3971 merged 4 commits intoSUNET:mainfrom
sirosfoundation:feat/go-cryptoutil-integration
Mar 26, 2026
Merged

feat: integrate go-cryptoutil for extensible certificate parsing#335
masv3971 merged 4 commits intoSUNET:mainfrom
sirosfoundation:feat/go-cryptoutil-integration

Conversation

@leifj
Copy link
Copy Markdown
Contributor

@leifj leifj commented Mar 24, 2026

Summary

Integrates go-cryptoutil to enable extensible certificate parsing across the vc codebase. This allows non-standard X.509 algorithms (e.g. brainpool curves used in EU eIDAS trust services) to be handled transparently through a pluggable *cryptoutil.Extensions parameter.

Changes

New file

  • pkg/pki/cryptoext.go — Shared ParseCertificate(der, ext) helper that delegates to extensions when available, falls back to stdlib x509.ParseCertificate when nil.

Updated packages

Package Change
pkg/mdoc/cose.go GetCertificateChainFromSign1 accepts variadic *cryptoutil.Extensions
pkg/mdoc/verifier.go CryptoExt field on VerifierConfig, wired through to certificate chain parsing
pkg/sdjwtvc/verification.go CryptoExt field on VerificationOptions, used in x5c header parsing
pkg/openid4vp/trust_service.go ExtractPublicKeyFromX5C accepts variadic extensions
pkg/pki/keyloader.go CryptoExt field on KeyLoader
internal/issuer/apiv1/client.go Extension-aware PEM certificate chain parsing
internal/wallet/apiv1/vp.go Extension-aware x5c leaf certificate parsing

Design principles

  • Zero breaking changes: All new parameters use variadic ...*cryptoutil.Extensions or struct fields, so existing callers work unchanged with nil/zero values.
  • Nil-safe: Every call site falls back to standard x509.ParseCertificate when extensions are nil.
  • Opt-in: Callers configure a *cryptoutil.Extensions (with registered brainpool or other parsers) only when needed.

Dependency

Adds github.com/sirosfoundation/go-cryptoutil v0.2.0 — a lightweight module (~500 LOC) providing pluggable certificate parsers, signature verifiers, and a cross-protocol algorithm registry.

Testing

All existing tests pass unchanged. The integration is transparent — no behavioral change unless extensions are explicitly configured.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Integrates github.com/sirosfoundation/go-cryptoutil to allow opt-in, extension-aware X.509 certificate parsing (e.g., brainpool curves) by threading a *cryptoutil.Extensions through verification/parsing paths while preserving default stdlib behavior when extensions are nil.

Changes:

  • Added pkg/pki.ParseCertificate(der, ext) helper that delegates to ext.ParseCertificate when provided, otherwise uses x509.ParseCertificate.
  • Plumbed optional crypto extensions into SD-JWT (VerificationOptions), mdoc verifier config (VerifierConfig), and COSE x5chain parsing (GetCertificateChainFromSign1).
  • Updated issuer/wallet certificate parsing call sites to use the new helper (currently passing nil extensions).

Reviewed changes

Copilot reviewed 9 out of 10 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
pkg/sdjwtvc/verification.go Adds CryptoExt to options; uses it when parsing x5c headers.
pkg/pki/keyloader.go Adds CryptoExt field and routes PEM chain parsing through pki.ParseCertificate.
pkg/pki/cryptoext.go New shared helper for extension-aware DER certificate parsing.
pkg/openid4vp/trust_service.go Extends ExtractPublicKeyFromX5C to optionally use *cryptoutil.Extensions.
pkg/mdoc/verifier.go Adds CryptoExt to verifier config and passes it to COSE chain extraction.
pkg/mdoc/cose.go Extends GetCertificateChainFromSign1 to optionally parse certs via extensions.
internal/wallet/apiv1/vp.go Switches request-object x5c leaf parsing to pki.ParseCertificate (currently ext=nil).
internal/issuer/apiv1/client.go Switches PEM certificate chain parsing to pki.ParseCertificate (currently ext=nil).
go.mod Adds go-cryptoutil requirement (currently marked // indirect).
go.sum Adds checksum entries for go-cryptoutil.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@leifj leifj force-pushed the feat/go-cryptoutil-integration branch from 14d936b to 7171027 Compare March 25, 2026 10:40
@masv3971 masv3971 requested a review from Copilot March 25, 2026 14:27
Leif Johansson added 3 commits March 25, 2026 15:29
Add extension-aware certificate parsing across mdoc, SD-JWT VC, OpenID4VP,
PKI, and issuer/wallet packages:

- pkg/pki/cryptoext.go: shared ParseCertificate helper
- pkg/mdoc/cose.go: GetCertificateChainFromSign1 with variadic ext
- pkg/mdoc/verifier.go: CryptoExt on VerifierConfig, wired to chain parsing
- pkg/sdjwtvc/verification.go: CryptoExt on VerificationOptions
- pkg/openid4vp/trust_service.go: extension-aware x5c parsing
- pkg/pki/keyloader.go: CryptoExt on KeyLoader
- internal/issuer/apiv1/client.go: extension-aware PEM chain parsing
- internal/wallet/apiv1/vp.go: extension-aware x5c leaf parsing

All sites fall back to stdlib x509.ParseCertificate when extensions are nil.
Enables brainpool and other non-standard certificate algorithms.
- Remove // indirect marker from go-cryptoutil in go.mod
- Use pki.ParseCertificate in trust_service.go to centralize parsing logic
- Add NewKeyLoaderWithExtensions constructor and document thread safety
- Add tests for cryptoext.go, keyloader extensions, and jose.ParseX5CHeader
- Coverage for new code: cryptoext.go 100%, x5c.go ParseX5CHeader 100%
- Lowercase error string in jws_signature.go (ST1005)
- Remove redundant nil checks before len() in claims_extractor.go (S1009)
- Add error checking for json.Unmarshal in vc20_vp_builder_test.go (errcheck)
@leifj leifj force-pushed the feat/go-cryptoutil-integration branch from 1eec103 to d18f72c Compare March 25, 2026 14:30
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 16 out of 17 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Simplifies test code by using pem.EncodeToMemory rather than
manually building PEM with base64 line wrapping.
@leifj
Copy link
Copy Markdown
Contributor Author

leifj commented Mar 25, 2026

Summary of Changes

This PR integrates go-cryptoutil to enable extensible certificate parsing for non-standard X.509 algorithms (brainpool curves, EU eIDAS certificates).

Key Changes:

  • pkg/pki/cryptoext.go: New ParseCertificate helper that wraps go-cryptoutil with fallback to stdlib
  • pkg/pki/keyloader.go: Added CryptoExt field and NewKeyLoaderWithExtensions() constructor with thread-safety documentation
  • pkg/jose/x5c.go: Updated ParseX5CHeader() with variadic extensions parameter for future extensibility
  • pkg/openid4vp/trust_service.go: Refactored to use centralized pki.ParseCertificate

Test Coverage:

  • pkg/pki/cryptoext_test.go: 100% coverage of new ParseCertificate helper
  • pkg/pki/keyloader_ext_test.go: Tests for KeyLoader extension support
  • pkg/jose/x5c_test.go: 100% coverage for ParseX5CHeader with extension tests

Code Quality:

  • Fixed staticcheck findings (ST1005, S1009, errcheck)
  • All review comments addressed

Ready for merge.

@sonarqubecloud
Copy link
Copy Markdown

@masv3971 masv3971 merged commit 035cfc3 into SUNET:main Mar 26, 2026
4 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants