pax_global_header00006660000000000000000000000064145660635270014530gustar00rootroot0000000000000052 comment=d6236d5cdf87770cf91ae58586fc35ac4ec209ea didx509go-0.0.3/000077500000000000000000000000001456606352700132445ustar00rootroot00000000000000didx509go-0.0.3/.github/000077500000000000000000000000001456606352700146045ustar00rootroot00000000000000didx509go-0.0.3/.github/dependabot.yml000066400000000000000000000007201456606352700174330ustar00rootroot00000000000000# To get started with Dependabot version updates, you'll need to specify which # package ecosystems to update and where the package manifests are located. # Please see the documentation for all configuration options: # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates version: 2 updates: - package-ecosystem: "gomod" directory: "/" # Location of package manifests schedule: interval: "weekly" didx509go-0.0.3/.github/workflows/000077500000000000000000000000001456606352700166415ustar00rootroot00000000000000didx509go-0.0.3/.github/workflows/ci.yml000066400000000000000000000010131456606352700177520ustar00rootroot00000000000000# This workflow will build a golang project # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go name: CI on: push: branches: [ "main" ] pull_request: branches: [ "main" ] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Set up Go uses: actions/setup-go@v3 with: go-version: '1.20' - name: Build run: go build -v ./... - name: Test run: go test -v ./... didx509go-0.0.3/.gitignore000066400000000000000000000135621456606352700152430ustar00rootroot00000000000000## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. ## ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore # User-specific files *.rsuser *.suo *.user *.userosscache *.sln.docstates # User-specific files (MonoDevelop/Xamarin Studio) *.userprefs # Mono auto generated files mono_crash.* # Build results [Dd]ebug/ [Dd]ebugPublic/ [Rr]elease/ [Rr]eleases/ x64/ x86/ [Aa][Rr][Mm]/ [Aa][Rr][Mm]64/ bld/ [Bb]in/ [Oo]bj/ [Ll]og/ [Ll]ogs/ # Visual Studio 2015/2017 cache/options directory .vs/ # Uncomment if you have tasks that create the project's static files in wwwroot #wwwroot/ # Visual Studio 2017 auto generated files Generated\ Files/ # MSTest test Results [Tt]est[Rr]esult*/ [Bb]uild[Ll]og.* # NUnit *.VisualState.xml TestResult.xml nunit-*.xml # Build Results of an ATL Project [Dd]ebugPS/ [Rr]eleasePS/ dlldata.c # Benchmark Results BenchmarkDotNet.Artifacts/ # .NET Core project.lock.json project.fragment.lock.json artifacts/ # StyleCop StyleCopReport.xml # Files built by Visual Studio *_i.c *_p.c *_h.h *.ilk *.meta *.obj *.iobj *.pch *.pdb *.ipdb *.pgc *.pgd *.rsp *.sbr *.tlb *.tli *.tlh *.tmp *.tmp_proj *_wpftmp.csproj *.log *.vspscc *.vssscc .builds *.pidb *.svclog *.scc # Chutzpah Test files _Chutzpah* # Visual C++ cache files ipch/ *.aps *.ncb *.opendb *.opensdf *.sdf *.cachefile *.VC.db *.VC.VC.opendb # Visual Studio profiler *.psess *.vsp *.vspx *.sap # Visual Studio Trace Files *.e2e # TFS 2012 Local Workspace $tf/ # Guidance Automation Toolkit *.gpState # ReSharper is a .NET coding add-in _ReSharper*/ *.[Rr]e[Ss]harper *.DotSettings.user # TeamCity is a build add-in _TeamCity* # DotCover is a Code Coverage Tool *.dotCover # AxoCover is a Code Coverage Tool .axoCover/* !.axoCover/settings.json # Visual Studio code coverage results *.coverage *.coveragexml # NCrunch _NCrunch_* .*crunch*.local.xml nCrunchTemp_* # MightyMoose *.mm.* AutoTest.Net/ # Web workbench (sass) .sass-cache/ # Installshield output folder [Ee]xpress/ # DocProject is a documentation generator add-in DocProject/buildhelp/ DocProject/Help/*.HxT DocProject/Help/*.HxC DocProject/Help/*.hhc DocProject/Help/*.hhk DocProject/Help/*.hhp DocProject/Help/Html2 DocProject/Help/html # Click-Once directory publish/ # Publish Web Output *.[Pp]ublish.xml *.azurePubxml # Note: Comment the next line if you want to checkin your web deploy settings, # but database connection strings (with potential passwords) will be unencrypted *.pubxml *.publishproj # Microsoft Azure Web App publish settings. Comment the next line if you want to # checkin your Azure Web App publish settings, but sensitive information contained # in these scripts will be unencrypted PublishScripts/ # NuGet Packages *.nupkg # NuGet Symbol Packages *.snupkg # The packages folder can be ignored because of Package Restore **/[Pp]ackages/* # except build/, which is used as an MSBuild target. !**/[Pp]ackages/build/ # Uncomment if necessary however generally it will be regenerated when needed #!**/[Pp]ackages/repositories.config # NuGet v3's project.json files produces more ignorable files *.nuget.props *.nuget.targets # Microsoft Azure Build Output csx/ *.build.csdef # Microsoft Azure Emulator ecf/ rcf/ # Windows Store app package directories and files AppPackages/ BundleArtifacts/ Package.StoreAssociation.xml _pkginfo.txt *.appx *.appxbundle *.appxupload # Visual Studio cache files # files ending in .cache can be ignored *.[Cc]ache # but keep track of directories ending in .cache !?*.[Cc]ache/ # Others ClientBin/ ~$* *~ *.dbmdl *.dbproj.schemaview *.jfm *.pfx *.publishsettings orleans.codegen.cs # Including strong name files can present a security risk # (https://github.com/github/gitignore/pull/2483#issue-259490424) #*.snk # Since there are multiple workflows, uncomment next line to ignore bower_components # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) #bower_components/ # RIA/Silverlight projects Generated_Code/ # Backup & report files from converting an old project file # to a newer Visual Studio version. Backup files are not needed, # because we have git ;-) _UpgradeReport_Files/ Backup*/ UpgradeLog*.XML UpgradeLog*.htm ServiceFabricBackup/ *.rptproj.bak # SQL Server files *.mdf *.ldf *.ndf # Business Intelligence projects *.rdl.data *.bim.layout *.bim_*.settings *.rptproj.rsuser *- [Bb]ackup.rdl *- [Bb]ackup ([0-9]).rdl *- [Bb]ackup ([0-9][0-9]).rdl # Microsoft Fakes FakesAssemblies/ # GhostDoc plugin setting file *.GhostDoc.xml # Node.js Tools for Visual Studio .ntvs_analysis.dat node_modules/ # Visual Studio 6 build log *.plg # Visual Studio 6 workspace options file *.opt # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) *.vbw # Visual Studio LightSwitch build output **/*.HTMLClient/GeneratedArtifacts **/*.DesktopClient/GeneratedArtifacts **/*.DesktopClient/ModelManifest.xml **/*.Server/GeneratedArtifacts **/*.Server/ModelManifest.xml _Pvt_Extensions # Paket dependency manager .paket/paket.exe paket-files/ # FAKE - F# Make .fake/ # CodeRush personal settings .cr/personal # Python Tools for Visual Studio (PTVS) __pycache__/ *.pyc # Cake - Uncomment if you are using it # tools/** # !tools/packages.config # Tabs Studio *.tss # Telerik's JustMock configuration file *.jmconfig # BizTalk build output *.btp.cs *.btm.cs *.odx.cs *.xsd.cs # OpenCover UI analysis results OpenCover/ # Azure Stream Analytics local run output ASALocalRun/ # MSBuild Binary and Structured Log *.binlog # NVidia Nsight GPU debugger configuration file *.nvuser # MFractors (Xamarin productivity tool) working folder .mfractor/ # Local History for Visual Studio .localhistory/ # BeatPulse healthcheck temp database healthchecksdb # Backup folder for Package Reference Convert tool in Visual Studio 2017 MigrationBackup/ # Ionide (cross platform F# VS Code tools) working folder .ionide/ didx509go-0.0.3/CODE_OF_CONDUCT.md000066400000000000000000000006741456606352700160520ustar00rootroot00000000000000# Microsoft Open Source Code of Conduct This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). Resources: - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns didx509go-0.0.3/LICENSE000066400000000000000000000021651456606352700142550ustar00rootroot00000000000000 MIT License Copyright (c) Microsoft Corporation. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE didx509go-0.0.3/README.md000066400000000000000000000033621456606352700145270ustar00rootroot00000000000000# didx509go [![go.dev](https://pkg.go.dev/badge/github.com/microsoft/didx509go.svg)](https://pkg.go.dev/github.com/microsoft/didx509go) [![tests](https://github.com/microsoft/didx509go/actions/workflows/ci.yml/badge.svg)](https://github.com/microsoft/didx509go/actions?query=workflow%3Aci) DID:x509 resolver for Go ## Contributing This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com. When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA. This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. ## Trademarks This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow [Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general). Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos are subject to those third-party's policies. didx509go-0.0.3/SECURITY.md000066400000000000000000000053051456606352700150400ustar00rootroot00000000000000 ## Security Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below. ## Reporting Security Issues **Please do not report security vulnerabilities through public GitHub issues.** Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report). If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey). You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) * Full paths of source file(s) related to the manifestation of the issue * The location of the affected source code (tag/branch/commit or direct URL) * Any special configuration required to reproduce the issue * Step-by-step instructions to reproduce the issue * Proof-of-concept or exploit code (if possible) * Impact of the issue, including how an attacker might exploit the issue This information will help us triage your report more quickly. If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs. ## Preferred Languages We prefer all communications to be in English. ## Policy Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd). didx509go-0.0.3/SUPPORT.md000066400000000000000000000005671456606352700147520ustar00rootroot00000000000000# Support ## How to file issues and get help This project uses GitHub Issues to track bugs and feature requests. Please search the existing issues before filing new issues to avoid duplicates. For new issues, file your bug or feature request as a new Issue. ## Microsoft Support Policy Support for this project is limited to the resources listed above. didx509go-0.0.3/go.mod000066400000000000000000000010471456606352700143540ustar00rootroot00000000000000module github.com/Microsoft/didx509go go 1.20 require github.com/lestrrat-go/jwx v1.2.28 require ( github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/goccy/go-json v0.10.2 // indirect github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect github.com/lestrrat-go/blackmagic v1.0.2 // indirect github.com/lestrrat-go/httpcc v1.0.1 // indirect github.com/lestrrat-go/iter v1.0.2 // indirect github.com/lestrrat-go/option v1.0.1 // indirect github.com/pkg/errors v0.9.1 // indirect golang.org/x/crypto v0.17.0 // indirect ) didx509go-0.0.3/go.sum000066400000000000000000000164361456606352700144110ustar00rootroot00000000000000github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A= github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y= github.com/lestrrat-go/blackmagic v1.0.1 h1:lS5Zts+5HIC/8og6cGHb0uCcNCa3OUt1ygh3Qz2Fe80= github.com/lestrrat-go/blackmagic v1.0.1/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU= github.com/lestrrat-go/blackmagic v1.0.2 h1:Cg2gVSc9h7sz9NOByczrbUvLopQmXrfFx//N+AkAr5k= github.com/lestrrat-go/blackmagic v1.0.2/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU= github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE= github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E= github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI= github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4= github.com/lestrrat-go/jwx v1.2.26 h1:4iFo8FPRZGDYe1t19mQP0zTRqA7n8HnJ5lkIiDvJcB0= github.com/lestrrat-go/jwx v1.2.26/go.mod h1:MaiCdGbn3/cckbOFSCluJlJMmp9dmZm5hDuIkx8ftpQ= github.com/lestrrat-go/jwx v1.2.28 h1:uadI6o0WpOVrBSf498tRXZIwPpEtLnR9CvqPFXeI5sA= github.com/lestrrat-go/jwx v1.2.28/go.mod h1:nF+91HEMh/MYFVwKPl5HHsBGMPscqbQb+8IDQdIazP8= github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU= github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= didx509go-0.0.3/pkg/000077500000000000000000000000001456606352700140255ustar00rootroot00000000000000didx509go-0.0.3/pkg/did-x509-resolver/000077500000000000000000000000001456606352700171275ustar00rootroot00000000000000didx509go-0.0.3/pkg/did-x509-resolver/resolver.go000066400000000000000000000312041456606352700213170ustar00rootroot00000000000000package didx509resolver import ( "crypto/sha256" "crypto/sha512" "crypto/x509" "encoding/asn1" "encoding/base64" "encoding/json" "encoding/pem" "errors" "fmt" "net/url" "strconv" "strings" "github.com/lestrrat-go/jwx/jwk" ) func VerifyCertificateChain(chain []*x509.Certificate, trustedRoots []*x509.Certificate, ignoreTime bool) ([][]*x509.Certificate, error) { roots := x509.NewCertPool() for _, cert := range trustedRoots { roots.AddCert(cert) } intermediates := x509.NewCertPool() for _, c := range chain[1 : len(chain)-1] { intermediates.AddCert(c) } opts := x509.VerifyOptions{ Roots: roots, Intermediates: intermediates, KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageAny}, CurrentTime: chain[0].NotAfter, // TODO: Figure out how to disable expiry checks? } return chain[0].Verify(opts) } func checkFingerprint(chain []*x509.Certificate, caFingerprintAlg, caFingerprint string) error { expectedCaFingerprints := make(map[string]struct{}) for _, cert := range chain[1:] { var n struct{} var hash []byte switch caFingerprintAlg { case "sha256": x := sha256.Sum256(cert.Raw) hash = x[:] case "sha384": x := sha512.Sum384(cert.Raw) hash = x[:] case "sha512": x := sha512.Sum512(cert.Raw) hash = x[:] default: return errors.New("unsupported hash algorithm") } hashStr := base64.RawURLEncoding.EncodeToString(hash) expectedCaFingerprints[hashStr] = n } if _, found := expectedCaFingerprints[caFingerprint]; !found { return errors.New("unexpected certificate fingerprint") } return nil } func oidFromString(s string) (*asn1.ObjectIdentifier, error) { tokens := strings.Split(s, ".") var ints []int for _, x := range tokens { i, err := strconv.Atoi(x) if err != nil { return nil, errors.New("invalid OID") } ints = append(ints, i) } result := asn1.ObjectIdentifier(ints) return &result, nil } func checkHasSan(sanType string, value string, cert *x509.Certificate) error { switch sanType { case "dns": for _, name := range cert.DNSNames { if name == value { return nil } } case "email": for _, email := range cert.EmailAddresses { if email == value { return nil } } case "ipaddress": for _, ip := range cert.IPAddresses { if ip.String() == value { return nil } } case "uri": for _, uri := range cert.URIs { if uri.String() == value { return nil } } default: return fmt.Errorf("unknown SAN type: %s", sanType) } return fmt.Errorf("SAN not found: %s", value) } // The x509 package/module doesn't export these. // they are derived from https://www.rfc-editor.org/rfc/rfc5280 RFC 5280, 4.2.1.12 Extended Key Usage // and can never change var ( oidExtKeyUsageAny = asn1.ObjectIdentifier{2, 5, 29, 37, 0} oidExtKeyUsageServerAuth = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 1} oidExtKeyUsageClientAuth = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 2} oidExtKeyUsageCodeSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 3} oidExtKeyUsageEmailProtection = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 4} oidExtKeyUsageIPSECEndSystem = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 5} oidExtKeyUsageIPSECTunnel = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 6} oidExtKeyUsageIPSECUser = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 7} oidExtKeyUsageTimeStamping = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 8} oidExtKeyUsageOCSPSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 9} oidExtKeyUsageMicrosoftServerGatedCrypto = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 3} oidExtKeyUsageNetscapeServerGatedCrypto = asn1.ObjectIdentifier{2, 16, 840, 1, 113730, 4, 1} oidExtKeyUsageMicrosoftCommercialCodeSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 2, 1, 22} oidExtKeyUsageMicrosoftKernelCodeSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 61, 1, 1} ) var extKeyUsageOIDs = []struct { extKeyUsage x509.ExtKeyUsage oid asn1.ObjectIdentifier }{ {x509.ExtKeyUsageAny, oidExtKeyUsageAny}, {x509.ExtKeyUsageServerAuth, oidExtKeyUsageServerAuth}, {x509.ExtKeyUsageClientAuth, oidExtKeyUsageClientAuth}, {x509.ExtKeyUsageCodeSigning, oidExtKeyUsageCodeSigning}, {x509.ExtKeyUsageEmailProtection, oidExtKeyUsageEmailProtection}, {x509.ExtKeyUsageIPSECEndSystem, oidExtKeyUsageIPSECEndSystem}, {x509.ExtKeyUsageIPSECTunnel, oidExtKeyUsageIPSECTunnel}, {x509.ExtKeyUsageIPSECUser, oidExtKeyUsageIPSECUser}, {x509.ExtKeyUsageTimeStamping, oidExtKeyUsageTimeStamping}, {x509.ExtKeyUsageOCSPSigning, oidExtKeyUsageOCSPSigning}, {x509.ExtKeyUsageMicrosoftServerGatedCrypto, oidExtKeyUsageMicrosoftServerGatedCrypto}, {x509.ExtKeyUsageNetscapeServerGatedCrypto, oidExtKeyUsageNetscapeServerGatedCrypto}, {x509.ExtKeyUsageMicrosoftCommercialCodeSigning, oidExtKeyUsageMicrosoftCommercialCodeSigning}, {x509.ExtKeyUsageMicrosoftKernelCodeSigning, oidExtKeyUsageMicrosoftKernelCodeSigning}, } func OidFromExtKeyUsage(eku x509.ExtKeyUsage) (oid asn1.ObjectIdentifier, ok bool) { for _, pair := range extKeyUsageOIDs { if eku == pair.extKeyUsage { return pair.oid, true } } return } // did:x509 examples // // did:x509:0:sha256:WE4P5dd8DnLHSkyHaIjhp4udlkF9LqoKwCvu9gl38jk::subject:C:US:ST:California:L:San%20Francisco:O:GitHub%2C%20Inc. // did:x509:0:sha256:I5ni_nuWegx4NiLaeGabiz36bDUhDDiHEFl8HXMA_4o::subject:CN:Test%20Leaf%20%28DO%20NOT%20TRUST%20 // // see https://github.com/microsoft/did-x509/blob/main/specification.md and https://www.w3.org/TR/2022/REC-did-core-20220719/ // check that the did "did" matches the public cert chain "chain" func verifyDid(chain []*x509.Certificate, did string) error { var topTokens = strings.Split(did, "::") if len(topTokens) <= 1 { return errors.New("invalid DID string") } var pretokens = strings.Split(topTokens[0], ":") if len(pretokens) < 5 || pretokens[0] != "did" || pretokens[1] != "x509" { return errors.New("unsupported method/prefix") } if pretokens[2] != "0" { return errors.New("unsupported did:x509 version") } caFingerprintAlg := pretokens[3] caFingerprint := pretokens[4] policies := topTokens[1:] if len(chain) < 2 { return errors.New("certificate chain too short") } err := checkFingerprint(chain, caFingerprintAlg, caFingerprint) if err != nil { return err } for _, policy := range policies { parts := strings.Split(policy, ":") if len(parts) < 2 { return errors.New("invalid policy") } policyName, args := parts[0], parts[1:] switch policyName { case "subject": if len(args) == 0 || len(args)%2 != 0 { return errors.New("key-value pairs required") } if len(args) < 2 { return errors.New("at least one key-value pair is required") } // Walk the x509 subject description (a list of key:value pairs like "CN:ContainerPlat" saying the subject common // name is ContainerPlat) extracting the various fields and checking they do not occur more than once. var seenFields []string for i := 0; i < len(args); i += 2 { k := strings.ToUpper(args[i]) v, err := url.QueryUnescape(args[i+1]) if err != nil { return fmt.Errorf("urlUnescape failed: %w", err) } for _, sk := range seenFields { if sk == k { return fmt.Errorf("duplicate field '%s'", k) } } seenFields = append(seenFields, k) leaf := chain[0] var fieldValues []string switch k { case "C": fieldValues = leaf.Subject.Country case "O": fieldValues = leaf.Subject.Organization case "OU": fieldValues = leaf.Subject.OrganizationalUnit case "L": fieldValues = leaf.Subject.Locality case "S": fieldValues = leaf.Subject.Province case "STREET": fieldValues = leaf.Subject.StreetAddress case "POSTALCODE": fieldValues = leaf.Subject.PostalCode case "SERIALNUMBER": fieldValues = []string{leaf.Subject.SerialNumber} case "CN": fieldValues = []string{leaf.Subject.CommonName} default: for _, aav := range leaf.Subject.Names { if aav.Type.String() == k { fieldValues = []string{aav.Value.(string)} break } } if len(fieldValues) == 0 { return fmt.Errorf("unsupported subject key: %s", k) } } found := false for _, fv := range fieldValues { if fv == v { found = true break } } if !found { return fmt.Errorf("invalid subject value: %s=%s", k, v) } } case "san": if len(args) != 2 { return fmt.Errorf("exactly one SAN type and value required") } sanType := args[0] sanValue, err := url.QueryUnescape(args[1]) if err != nil { return fmt.Errorf("url.QueryUnescape failed: %w", err) } err = checkHasSan(sanType, sanValue, chain[0]) if err != nil { return err } case "eku": if len(args) != 1 { return errors.New("exactly one EKU required") } ekuOid, err := oidFromString(args[0]) if err != nil { return fmt.Errorf("oidFromString failed: %w", err) } if len(chain[0].UnknownExtKeyUsage) == 0 { return errors.New("no EKU extension in certificate") } foundEku := false for _, certEku := range chain[0].ExtKeyUsage { certEkuOid, ok := OidFromExtKeyUsage(certEku) if ok && certEkuOid.Equal(*ekuOid) { foundEku = true break } } for _, certEkuOid := range chain[0].UnknownExtKeyUsage { if certEkuOid.Equal(*ekuOid) { foundEku = true break } } if !foundEku { return fmt.Errorf("EKU not found: %s", ekuOid) } case "fulcio-issuer": if len(args) != 1 { return errors.New("excessive arguments to fulcio-issuer") } decodedArg, err := url.QueryUnescape(args[0]) if err != nil { return fmt.Errorf("urlUnescape failed: %w", err) } fulcioIssuer := "https://" + decodedArg fulcioIssuerOid, err := oidFromString("1.3.6.1.4.1.57264.1.1") if err != nil { return fmt.Errorf("oidFromString failed: %w", err) } found := false for _, ext := range chain[0].Extensions { if ext.Id.Equal(*fulcioIssuerOid) { if string(ext.Value) == fulcioIssuer { found = true break } } } if !found { return fmt.Errorf("invalid fulcio-issuer: %s", fulcioIssuer) } default: return fmt.Errorf("unsupported did:x509 policy name '%s'", policyName) } } return nil } func createDidDocument(did string, chain []*x509.Certificate) (string, error) { format := ` { "@context": "https://www.w3.org/ns/did/v1", "id": "%s", "verificationMethod": [{ "id": "%[1]s#key-1", "type": "JsonWebKey2020", "controller": "%[1]s", "publicKeyJwk": %s }] %s %s }` includeAssertionMethod := chain[0].KeyUsage == 0 || (chain[0].KeyUsage&x509.KeyUsageDigitalSignature) != 0 includeKeyAgreement := chain[0].KeyUsage == 0 || (chain[0].KeyUsage&x509.KeyUsageKeyAgreement) != 0 if !includeAssertionMethod && !includeKeyAgreement { return "", errors.New("leaf certificate key usage must include digital signature or key agreement") } am := "" ka := "" if includeAssertionMethod { am = fmt.Sprintf(",\"assertionMethod\": \"%s#key-1\"", did) } if includeKeyAgreement { ka = fmt.Sprintf(",\"keyAgreement\": \"%s#key-1\"", did) } leaf, err := jwk.New(chain[0].PublicKey) if err != nil { return "", err } jleaf, err := json.Marshal(leaf) if err != nil { return "", err } doc := fmt.Sprintf(format, did, jleaf, am, ka) return doc, nil } func parsePemChain(chainPem string) ([]*x509.Certificate, error) { var chain = []*x509.Certificate{} bs := []byte(chainPem) for block, rest := pem.Decode(bs); block != nil; block, rest = pem.Decode(rest) { if block.Type == "CERTIFICATE" { cert, err := x509.ParseCertificate(block.Bytes) if err != nil { return []*x509.Certificate{}, fmt.Errorf("certificate parser failed: %w", err) } chain = append(chain, cert) } } return chain, nil } func Resolve(chainPem string, did string, ignoreTime bool) (string, error) { chain, err := parsePemChain(chainPem) if err != nil { return "", err } if len(chain) == 0 { return "", errors.New("no certificate chain") } // The last certificate in the chain is assumed to be the trusted root. roots := []*x509.Certificate{chain[len(chain)-1]} chains, err := VerifyCertificateChain(chain, roots, ignoreTime) if err != nil { return "", fmt.Errorf("certificate chain verification failed: %w", err) } for _, chain := range chains { err = verifyDid(chain, did) if err != nil { return "", fmt.Errorf("DID verification failed: %w", err) } } doc, err := createDidDocument(did, chain) if err != nil { return "", fmt.Errorf("DID document creation failed: %w", err) } return doc, nil } didx509go-0.0.3/pkg/did-x509-resolver/resolver_test.go000066400000000000000000000114711456606352700223620ustar00rootroot00000000000000package didx509resolver import ( "os" "testing" ) func checkFailed(t *testing.T, err error) { t.Helper() if err == nil { t.Errorf("error: should have failed") } } func checkOk(t *testing.T, err error) { t.Helper() if err != nil { t.Errorf("error: rejected valid DID: %s", err) } } func loadCertificateChain(t *testing.T, path string) string { t.Helper() chain, err := os.ReadFile(path) if err != nil { t.Errorf("error: can't read file") } return string(chain) } func TestWrongPrefix(t *testing.T) { chain := loadCertificateChain(t, "test-data/ms-code-signing.pem") _, err := Resolve(chain, "djd:y508:1:abcd::", true) checkFailed(t, err) } func TestRootCA(t *testing.T) { chain := loadCertificateChain(t, "test-data/ms-code-signing.pem") _, err := Resolve(chain, "did:x509:0:sha256:hH32p4SXlD8n_HLrk_mmNzIKArVh0KkbCeh6eAftfGE::subject:CN:Microsoft%20Corporation", true) checkOk(t, err) } func TestIntermediateCA(t *testing.T) { chain := loadCertificateChain(t, "test-data/ms-code-signing.pem") _, err := Resolve(chain, "did:x509:0:sha256:VtqHIq_ZQGb_4eRZVHOkhUiSuEOggn1T-32PSu7R4Ys::subject:CN:Microsoft%20Corporation", true) checkOk(t, err) } func TestInvalidLeafCA(t *testing.T) { chain := loadCertificateChain(t, "test-data/ms-code-signing.pem") _, err := Resolve(chain, "did:x509:0:sha256:h::subject:CN:Microsoft%20Corporation", true) checkFailed(t, err) } func TestInvalidCA(t *testing.T) { chain := loadCertificateChain(t, "test-data/ms-code-signing.pem") _, err := Resolve(chain, "did:x509:0:sha256:abc::CN:Microsoft%20Corporation", true) checkFailed(t, err) } func TestMultiplePolicies(t *testing.T) { chain := loadCertificateChain(t, "test-data/ms-code-signing.pem") _, err := Resolve(chain, "did:x509:0:sha256:hH32p4SXlD8n_HLrk_mmNzIKArVh0KkbCeh6eAftfGE::eku:1.3.6.1.5.5.7.3.3::eku:1.3.6.1.4.1.311.10.3.21", true) checkOk(t, err) } func TestSubject(t *testing.T) { chain := loadCertificateChain(t, "test-data/ms-code-signing.pem") _, err := Resolve(chain, "did:x509:0:sha256:hH32p4SXlD8n_HLrk_mmNzIKArVh0KkbCeh6eAftfGE::subject:CN:Microsoft%20Corporation", true) checkOk(t, err) } func TestSubjectInvalidName(t *testing.T) { chain := loadCertificateChain(t, "test-data/ms-code-signing.pem") _, err := Resolve(chain, "did:x509:0:sha256:hH32p4SXlD8n_HLrk_mmNzIKArVh0KkbCeh6eAftfGE::subject:CN:MicrosoftCorporation", true) checkFailed(t, err) } func TestSubjectDuplicateField(t *testing.T) { chain := loadCertificateChain(t, "test-data/ms-code-signing.pem") _, err := Resolve(chain, "did:x509:0:sha256:hH32p4SXlD8n_HLrk_mmNzIKArVh0KkbCeh6eAftfGE::subject:CN:Microsoft%20Corporation:CN:Microsoft%20Corporation", true) checkFailed(t, err) } func TestSAN(t *testing.T) { chain := loadCertificateChain(t, "test-data/fulcio-email.pem") _, err := Resolve(chain, "did:x509:0:sha256:O6e2zE6VRp1NM0tJyyV62FNwdvqEsMqH_07P5qVGgME::san:email:igarcia%40suse.com", true) checkOk(t, err) } func TestSANInvalidType(t *testing.T) { chain := loadCertificateChain(t, "test-data/fulcio-email.pem") _, err := Resolve(chain, "did:x509:0:sha256:O6e2zE6VRp1NM0tJyyV62FNwdvqEsMqH_07P5qVGgME::san:uri:igarcia%40suse.com", true) checkFailed(t, err) } func TestSANInvalidValue(t *testing.T) { chain := loadCertificateChain(t, "test-data/fulcio-email.pem") _, err := Resolve(chain, "did:x509:0:sha256:O6e2zE6VRp1NM0tJyyV62FNwdvqEsMqH_07P5qVGgME::email:bob%40example.com", true) checkFailed(t, err) } func TestBadEKU(t *testing.T) { chain := loadCertificateChain(t, "test-data/ms-code-signing.pem") _, err := Resolve(chain, "did:x509:0:sha256:hH32p4SXlD8n_HLrk_mmNzIKArVh0KkbCeh6eAftfGE::eku:1.3.6.1.5.5.7.3.12", true) checkFailed(t, err) } func TestGoodEKU(t *testing.T) { chain := loadCertificateChain(t, "test-data/ms-code-signing.pem") _, err := Resolve(chain, "did:x509:0:sha256:hH32p4SXlD8n_HLrk_mmNzIKArVh0KkbCeh6eAftfGE::eku:1.3.6.1.4.1.311.10.3.21", true) checkOk(t, err) } func TestEKUInvalidValue(t *testing.T) { chain := loadCertificateChain(t, "test-data/ms-code-signing.pem") _, err := Resolve(chain, "did:x509:0:sha256:hH32p4SXlD8n_HLrk_mmNzIKArVh0KkbCeh6eAftfGE::eku:1.2.3", true) checkFailed(t, err) } func TestFulcioIssuerWithEmailSAN(t *testing.T) { chain := loadCertificateChain(t, "test-data/fulcio-email.pem") _, err := Resolve(chain, "did:x509:0:sha256:O6e2zE6VRp1NM0tJyyV62FNwdvqEsMqH_07P5qVGgME::fulcio-issuer:github.com%2Flogin%2Foauth::san:email:igarcia%40suse.com", true) checkOk(t, err) } func TestFulcioIssuerWithURISAN(t *testing.T) { chain := loadCertificateChain(t, "test-data/fulcio-github-actions.pem") _, err := Resolve(chain, "did:x509:0:sha256:O6e2zE6VRp1NM0tJyyV62FNwdvqEsMqH_07P5qVGgME::fulcio-issuer:token.actions.githubusercontent.com::san:uri:https%3A%2F%2Fgithub.com%2Fbrendancassells%2Fmcw-continuous-delivery-lab-files%2F.github%2Fworkflows%2Ffabrikam-web.yml%40refs%2Fheads%2Fmain", true) checkOk(t, err) } didx509go-0.0.3/pkg/did-x509-resolver/test-data/000077500000000000000000000000001456606352700210155ustar00rootroot00000000000000didx509go-0.0.3/pkg/did-x509-resolver/test-data/fulcio-email.pem000066400000000000000000000027571456606352700241010ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIICEDCCAZagAwIBAgITIK73YV52uJcmxL9ZeKo+wZbm3zAKBggqhkjOPQQDAzAq MRUwEwYDVQQKEwxzaWdzdG9yZS5kZXYxETAPBgNVBAMTCHNpZ3N0b3JlMB4XDTIy MDgwOTEyNDcxNFoXDTIyMDgwOTEyNTcxM1owADBZMBMGByqGSM49AgEGCCqGSM49 AwEHA0IABPmQP4xa5TxXg/HkUrw3CUcqmW6F5eEBQSU8tcGMIIzIHnMCVwTa4uoq ZGgdCN+0Erk+toNwkGG+pS3Qc2EocbejgcQwgcEwDgYDVR0PAQH/BAQDAgeAMBMG A1UdJQQMMAoGCCsGAQUFBwMDMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFJITi/Hz 4QkD5qz2gKoi4UBYfaRRMB8GA1UdIwQYMBaAFFjAHl+RRaVmqXrMkKGTItAqxcX6 MB4GA1UdEQEB/wQUMBKBEGlnYXJjaWFAc3VzZS5jb20wLAYKKwYBBAGDvzABAQQe aHR0cHM6Ly9naXRodWIuY29tL2xvZ2luL29hdXRoMAoGCCqGSM49BAMDA2gAMGUC MQDPO3n+JgPlTbXSQy942esSy7KQ6OI4N9Q9MsqN4UR2tkML7tUm5feKTQUkfwTs 6BsCMADuoj3fJGAiRDMlSphfrZ0tAEIFaVZtJmvKWXpElHQo9y39W0w9bJTEVgTa 4xvX4w== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIB9zCCAXygAwIBAgIUALZNAPFdxHPwjeDloDwyYChAO/4wCgYIKoZIzj0EAwMw KjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0y MTEwMDcxMzU2NTlaFw0zMTEwMDUxMzU2NThaMCoxFTATBgNVBAoTDHNpZ3N0b3Jl LmRldjERMA8GA1UEAxMIc2lnc3RvcmUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAT7 XeFT4rb3PQGwS4IajtLk3/OlnpgangaBclYpsYBr5i+4ynB07ceb3LP0OIOZdxex X69c5iVuyJRQ+Hz05yi+UF3uBWAlHpiS5sh0+H2GHE7SXrk1EC5m1Tr19L9gg92j YzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRY wB5fkUWlZql6zJChkyLQKsXF+jAfBgNVHSMEGDAWgBRYwB5fkUWlZql6zJChkyLQ KsXF+jAKBggqhkjOPQQDAwNpADBmAjEAj1nHeXZp+13NWBNa+EDsDP8G1WWg1tCM WP/WHPqpaVo0jhsweNFZgSs0eE7wYI4qAjEA2WB9ot98sIkoF3vZYdd3/VtWB5b9 TNMea7Ix/stJ5TfcLLeABLE4BNJOsQ4vnBHJ -----END CERTIFICATE----- didx509go-0.0.3/pkg/did-x509-resolver/test-data/fulcio-github-actions.pem000066400000000000000000000036351456606352700257260ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIDTzCCAtSgAwIBAgIUAOuDsEYQXN1cbwfqYOy5ADUqqDAwCgYIKoZIzj0EAwMw KjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0y MjA2MDkwMjM4MTJaFw0yMjA2MDkwMjQ4MTFaMAAwWTATBgcqhkjOPQIBBggqhkjO PQMBBwNCAAR8Qujd0dQ2F7uSANd+0M7VXVkhXlGvFERJc1oPxk+R/ApEantKDVd/ 5/+e2AOoS1ltjcZkCt1oP1mAZ/+2G3i6o4ICADCCAfwwDgYDVR0PAQH/BAQDAgeA MBMGA1UdJQQMMAoGCCsGAQUFBwMDMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFLcK jVaYdV1BcZimzcrE8foM3xAPMB8GA1UdIwQYMBaAFFjAHl+RRaVmqXrMkKGTItAq xcX6MIGFBgNVHREBAf8EezB5hndodHRwczovL2dpdGh1Yi5jb20vYnJlbmRhbmNh c3NlbGxzL21jdy1jb250aW51b3VzLWRlbGl2ZXJ5LWxhYi1maWxlcy8uZ2l0aHVi L3dvcmtmbG93cy9mYWJyaWthbS13ZWIueW1sQHJlZnMvaGVhZHMvbWFpbjAWBgor BgEEAYO/MAECBAhzY2hlZHVsZTA/BgorBgEEAYO/MAEFBDFicmVuZGFuY2Fzc2Vs bHMvbWN3LWNvbnRpbnVvdXMtZGVsaXZlcnktbGFiLWZpbGVzMDkGCisGAQQBg78w AQEEK2h0dHBzOi8vdG9rZW4uYWN0aW9ucy5naXRodWJ1c2VyY29udGVudC5jb20w NgYKKwYBBAGDvzABAwQoMTIxMDQ4ZDVkMmViNTc3OTg3NTFlY2Y1N2FjNWNlNTg2 NmVmMWEyZDAUBgorBgEEAYO/MAEEBAZEb2NrZXIwHQYKKwYBBAGDvzABBgQPcmVm cy9oZWFkcy9tYWluMAoGCCqGSM49BAMDA2kAMGYCMQDfg/L1SnH1EdkPtmPN197q Y+oc+mdFz1ica3Xlx8/En/JcxHUtBkHx1Lv5w++Wg3sCMQC4YKWGL0AfIIES1XT7 b96WTdxBSnBx2Nvrqg0VuzLvM+wIjaz3dXWf41eKB2sXvwo= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIB9zCCAXygAwIBAgIUALZNAPFdxHPwjeDloDwyYChAO/4wCgYIKoZIzj0EAwMw KjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0y MTEwMDcxMzU2NTlaFw0zMTEwMDUxMzU2NThaMCoxFTATBgNVBAoTDHNpZ3N0b3Jl LmRldjERMA8GA1UEAxMIc2lnc3RvcmUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAT7 XeFT4rb3PQGwS4IajtLk3/OlnpgangaBclYpsYBr5i+4ynB07ceb3LP0OIOZdxex X69c5iVuyJRQ+Hz05yi+UF3uBWAlHpiS5sh0+H2GHE7SXrk1EC5m1Tr19L9gg92j YzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRY wB5fkUWlZql6zJChkyLQKsXF+jAfBgNVHSMEGDAWgBRYwB5fkUWlZql6zJChkyLQ KsXF+jAKBggqhkjOPQQDAwNpADBmAjEAj1nHeXZp+13NWBNa+EDsDP8G1WWg1tCM WP/WHPqpaVo0jhsweNFZgSs0eE7wYI4qAjEA2WB9ot98sIkoF3vZYdd3/VtWB5b9 TNMea7Ix/stJ5TfcLLeABLE4BNJOsQ4vnBHJ -----END CERTIFICATE----- didx509go-0.0.3/pkg/did-x509-resolver/test-data/ms-code-signing.pem000066400000000000000000000153731456606352700245140ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIF/zCCA+egAwIBAgITMwAAAs+gJZDjEwTvFQAAAAACzzANBgkqhkiG9w0BAQsF ADB+MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSgwJgYDVQQD Ex9NaWNyb3NvZnQgQ29kZSBTaWduaW5nIFBDQSAyMDExMB4XDTIyMDUxMjIwNDYw NFoXDTIzMDUxMTIwNDYwNFowdDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hp bmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jw b3JhdGlvbjEeMBwGA1UEAxMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMIIBIjANBgkq hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs9HduD2rvmO+SGksB4HR+qvSK379St8N nUZBH8xBiQvt2zONOLUHWQibeBW4NLUfHfzMaOM77RhNlqPNiDRKhChlG1aHqEHS AaQBGrmr0ULGIzq+1YvqQufMGYBFfq0sc10UdvWqT0RjwkPQTu4bjg37zSYF9OcG xS9uGnPMdWRM0ThOsYUcDmMoCaJRebsLUBpMmYXkcUYXJrcSGAaUNd0wjhwIpEog OD+AbWW/7TPZOl+JciMj40a78EEXIc2p06lWHfe5hegQ7uGIlSAPG6zDzjhjNkzE 63/+GoqJU+6QLazbL5/y27ZDUAEYJokbb305A+dOp930CjTar3BvWQIDAQABo4IB fjCCAXowHwYDVR0lBBgwFgYKKwYBBAGCNwoDFQYIKwYBBQUHAwMwHQYDVR0OBBYE FHs4/z9sVQLrJJTk5iEaOQwyHU0iMFAGA1UdEQRJMEekRTBDMSkwJwYDVQQLEyBN aWNyb3NvZnQgT3BlcmF0aW9ucyBQdWVydG8gUmljbzEWMBQGA1UEBRMNMjMwMjE3 KzQ3MDUzMjAfBgNVHSMEGDAWgBRIbmTlUAXTgqoXNzcitW2oynUClTBUBgNVHR8E TTBLMEmgR6BFhkNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9N aWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3JsMGEGCCsGAQUFBwEBBFUwUzBR BggrBgEFBQcwAoZFaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0 cy9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3J0MAwGA1UdEwEB/wQCMAAw DQYJKoZIhvcNAQELBQADggIBAIBiYcrj5Ph8uwFKZXw0eCS9qv2lk4lZY4Semy2D 4sfKDNUqKsqP5Q0zJcAq3Z+uEKc9Q8boxkm9/3PPESQKWhTRqLY+LL2XTjbm1S/L AhtQ09ftHkxwienGU+Xo8ntz6Z7iQV2xCqjTMRWGFysEKgMgdAMPftWPXNa9k1G9 qEJpPcCLeiM6UEJdxnRDHKgDSugW4fYvcEXlOJJXn/VZr4fFJZ+xLGT+US/NwGwb 8DdoUYls2u5o2250nm0TA0cZkJCzrxzV6Fptv14jbPcTZpRU6D0zGSSLPaM2cA/A Q3yxRi9FZOpcbrJM+2Rp6aufmyxUgIN6MvG2IH2D++Xq3a4Zy+Gmce9thBRBff1i IROq6CdGJHbOVbfdivV3L7qBD9pQYqSKitq4fJV95iYEchgMoXGwkJwagXix+f8g jnOmlSjysSwzAmDwtAxUkX+lNoU5xUJLwf9/4nIXp7drjWptpn9IIiARLPFxLRYg 7S9digox7quSKM/xXb1bFzp346lwjuvK+QHC8pUOF8OojQ0YAZ+Q0EKKukchQ3wF 7RiHk/INqYgEFli/xpMzwVM2k91UlArvYylUKLGDGy8QabMosUrZdNQvBCWiePYR AaJR5t+IR5QeBNdaKEqh2EQ/VzCu7J247Q3UrZrPLUJ9bGp2INwL8jynhVOeZteW CEKV -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIHejCCBWKgAwIBAgIKYQ6Q0gAAAAAAAzANBgkqhkiG9w0BAQsFADCBiDELMAkG A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9z b2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTEwHhcNMTEwNzA4MjA1 OTA5WhcNMjYwNzA4MjEwOTA5WjB+MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2Fz aGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENv cnBvcmF0aW9uMSgwJgYDVQQDEx9NaWNyb3NvZnQgQ29kZSBTaWduaW5nIFBDQSAy MDExMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAq/D6chAcLq3YbqqC EE00uvK2WCGfQhsqa+laUKq4BjgaBEm6f8MMHt03a8YS2AvwOMKZBrDIOdUBFDFC 04kNeWSHfpRgJGyvnkmc6Whe0t+bU7IKLMOv2akrrnoJr9eWWcpgGgXpZnboMlIm Ei/nqwhQz7NEt13YxC4Ddato88tt8zpcoRb0RrrgOGSsbmQ1eKagYw8t00CT+OPe Bw3VXHmlSSnnDb6gE3e+lD3v++MrWhAfTVYoonpy4BI6t0le2O3tQ5GD2Xuye4Yb 2T6xjF3oiU+EGvKhL1nkkDstrjNYxbc+/jLTswM9sbKvkjh+0p2ALPVOVpEhNSXD OW5kf1O6nA+tGSOEy/S6A4aN91/w0FK/jJSHvMAhdCVfGCi2zCcoOCWYOUo2z3yx kq4cI6epZuxhH2rhKEmdX4jiJV3TIUs+UsS1Vz8kA/DRelsv1SPjcF0PUUZ3s/gA 4bysAoJf28AVs70b1FVL5zmhD+kjSbwYuER8ReTBw3J64HLnJN+/RpnF78IcV9uD jexNSTCnq47f7Fufr/zdsGbiwZeBe+3W7UvnSSmnEyimp31ngOaKYnhfsi+E11ec XL93KCjx7W3DKI8sj0A3T8HhhUSJxAlMxdSlQy90lfdu+HggWCwTXWCVmj5PM4Ta sIgX3p5O9JawvEagbJjS4NaIjAsCAwEAAaOCAe0wggHpMBAGCSsGAQQBgjcVAQQD AgEAMB0GA1UdDgQWBBRIbmTlUAXTgqoXNzcitW2oynUClTAZBgkrBgEEAYI3FAIE DB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNV HSMEGDAWgBRyLToCMZBDuRQFTuHqp8cx0SOJNDBaBgNVHR8EUzBRME+gTaBLhklo dHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNSb29D ZXJBdXQyMDExXzIwMTFfMDNfMjIuY3JsMF4GCCsGAQUFBwEBBFIwUDBOBggrBgEF BQcwAoZCaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29D ZXJBdXQyMDExXzIwMTFfMDNfMjIuY3J0MIGfBgNVHSAEgZcwgZQwgZEGCSsGAQQB gjcuAzCBgzA/BggrBgEFBQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3Br aW9wcy9kb2NzL3ByaW1hcnljcHMuaHRtMEAGCCsGAQUFBwICMDQeMiAdAEwAZQBn AGEAbABfAHAAbwBsAGkAYwB5AF8AcwB0AGEAdABlAG0AZQBuAHQALiAdMA0GCSqG SIb3DQEBCwUAA4ICAQBn8oalmOBUeRou09h0ZyKbC5YR4WOSmUKWfdJ5DJDBZV8u LD74w3LRbYP+vj/oCso7v0epo/Np22O/IjWll11lhJB9i0ZQVdgMknzSGksc8zxC i1LQsP1r4z4HLimb5j0bpdS1HXeUOeLpZMlEPXh6I/MTfaaQdION9MsmAkYqwooQ u6SpBQyb7Wj6aC6VoCo/KmtYSWMfCWluWpiW5IP0wI/zRive/DvQvTXvbiWu5a8n 7dDd8w6vmSiXmE0OPQvyCInWH8MyGOLwxS3OW560STkKxgrCxq2u5bLZ2xWIUUVY ODJxJxp/sfQn+N4sOiBpmLJZiWhub6e3dMNABQamASooPoI/E01mC8CzTfXhj38c bxV9Rad25UAqZaPDXVJihsMdYzaXht/a8/jyFqGaJ+HNpZfQ7l1jQeNbB5yHPgZ3 BtEGsXUfFL5hYbXw3MYbBL7fQccOKO7eZS/sl/ahXJbYANahRr1Z85elCUtIEJmA H9AAKcWxm6U/RXceNcbSoqKfenoi+kiVH6v7RyOA9Z74v2u3S5fi63V4GuzqN5l5 GEv/1rMjaHXmr/r8i+sLgOppO6/8MO0ETI7f33VtY5E90Z1WTk+/gFcioXgRMiF6 70EKsT/7qMykXcGhiJtXcVZOSEXAQsmbdlsKgEhr/Xmfwb1tbWrJUnMTDXpQzQ== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIF7TCCA9WgAwIBAgIQP4vItfyfspZDtWnWbELhRDANBgkqhkiG9w0BAQsFADCB iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1Jl ZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMp TWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTEwHhcNMTEw MzIyMjIwNTI4WhcNMzYwMzIyMjIxMzA0WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv c29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlm aWNhdGUgQXV0aG9yaXR5IDIwMTEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK AoICAQCygEGqNThNE3IyaCJNuLLx/9VSvGzH9dJKjDbu0cJcfoyKrq8TKG/Ac+M6 ztAlqFo6be+ouFmrEyNozQwph9FvgFyPRH9dkAFSWKxRxV8qh9zc2AodwQO5e7BW 6KPeZGHCnvjzfLnsDbVU/ky2ZU+I8JxImQxCCwl8MVkXeQZ4KI2JOkwDJb5xalwL 54RgpJki49KvhKSn+9GY7Qyp3pSJ4Q6g3MDOmT3qCFK7VnnkH4S6Hri0xElcTzFL h93dBWcmmYDgcRGjuKVB4qRTufcyKYMME782XgSzS0NHL2vikR7TmE/dQgfI6B0S /Jmpaz6SfsjWaTr8ZL22CZ3K/QwLopt3YEsDlKQwaRLWQi3BQUzK3Kr9j1uDRprZ /LHR47PJf0h6zSTwQY9cdNCssBAgBkm3xy0hyFfj0IbzA2j70M5xwYmZSmQBbP3s MJHPQTySx+W6hh1hhMdfgzlirrSSL0fzC/hV66AfWdC7dJse0Hbm8ukG1xDo+mTe acY1logC8Ea4PyeZb8txiSk190gWAjWP1Xl8TQLPX+uKg09FcYj5qQ1OcunCnAfP SRtOBA5jUYxe2ADBVSy2xuDCZU7JNDn1nLPEfuhhbhNfFcRf2X7tHc7uROzLLoax 7Dj2cO2rXBPB2Q8Nx4CyVe0096yb5MPa50c8prWPMd/FS6/r8QIDAQABo1EwTzAL BgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUci06AjGQQ7kU BU7h6qfHMdEjiTQwEAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZIhvcNAQELBQADggIB AH9yzw+3xRXbm8BJyiZb/p4T5tPw0tuXX/JLP02zrhmu7deXoKzvqTqjwkGw5biR nhOBJAPmCf0/V0A5ISRW0RAvS0CpNoZLtFNXmvvxfomPEf4YbFGq6O0JlbXlccmh 6Yd1phV/yX43VF50k8XDZ8wNT2uoFwxtCJJ+i92Bqi1wIcM9BhS7vyRep4TXPw8h Ir1LAAbblxzYXtTFC1yHblCk6MM4pPvLLMWSZpuFXst6bJN8gClYW1e1QGm6CHmm ZGIVnYeWRbVmIyADixxzoNOieTPgUFmG2y/lAiXqcyqfABTINseSO+lOAOzYVgm5 M0kS0lQLAausR7aRKX1MtHWAUgHoyoL2n8ysnI8X6i8msKtyrAv+nlEex0NVZ09R s1fWtuzuUrc66U7h14GIvE+OdbtLqPA1qibUZ2dJsnBMO5PcHd94kIZysjik0dyS TclY6ysSXNQ7roxrsIPlAT/4CTL2kzU0Iq/dNw13CYArzUgA8YyZGUcFAenRv9FO 0OYoQzeZpApKCNmacXPSqs0xE2N2oTdvkjgefRI8ZjLny23h/FKJ3crWZgWalmG+ oijHHKOnNlA8OqTfSm7mhzvO6/DggTedEzxSjr25HTTGHdUKaj2YKXCMiSrRq4IQ SB/c9O+lxbtVGjhjhE63bK2VVOxlIhBJF7jAHscPrFRH -----END CERTIFICATE-----