Test x509 intermediates correctly
This commit is contained in:
		
							
								
								
									
										11
									
								
								plugin/pkg/auth/authenticator/request/x509/testdata/client-expired.pem
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								plugin/pkg/auth/authenticator/request/x509/testdata/client-expired.pem
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					-----BEGIN CERTIFICATE-----
 | 
				
			||||||
 | 
					MIIBpTCCAUugAwIBAgIUPV4LAC5KK8YWY1FegyTuhkGUr3EwCgYIKoZIzj0EAwIw
 | 
				
			||||||
 | 
					GjEYMBYGA1UEAxMPSW50ZXJtZWRpYXRlLUNBMB4XDTkwMTIzMTIzNTkwMFoXDTkw
 | 
				
			||||||
 | 
					MTIzMTIzNTkwMFowFDESMBAGA1UEAxMJTXkgQ2xpZW50MFkwEwYHKoZIzj0CAQYI
 | 
				
			||||||
 | 
					KoZIzj0DAQcDQgAEyYUnseNUN87rfHgekrfZu5sj4wlt5LYr3JYZZkfSbsb+BW3/
 | 
				
			||||||
 | 
					RzX02ifjp+8w7mI4qUGg6y6J7oXHGFT3uj9kj6N1MHMwDgYDVR0PAQH/BAQDAgWg
 | 
				
			||||||
 | 
					MBMGA1UdJQQMMAoGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFKsX
 | 
				
			||||||
 | 
					EnXwDg8j2LIEM1QzmFrE6537MB8GA1UdIwQYMBaAFF+p0JcY31pz+mjNZnjv0Gum
 | 
				
			||||||
 | 
					92vZMAoGCCqGSM49BAMCA0gAMEUCIG4FBcb57oqOCoaFiJ+Yx6S0zkaash7bTv3V
 | 
				
			||||||
 | 
					CIy9JvFdAiEAy8bf2S9EkvZyURZ6ycgEMnekll57Ebze6rjlPx8+B1Y=
 | 
				
			||||||
 | 
					-----END CERTIFICATE-----
 | 
				
			||||||
							
								
								
									
										11
									
								
								plugin/pkg/auth/authenticator/request/x509/testdata/client-valid.pem
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								plugin/pkg/auth/authenticator/request/x509/testdata/client-valid.pem
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					-----BEGIN CERTIFICATE-----
 | 
				
			||||||
 | 
					MIIBqDCCAU2gAwIBAgIUfbqeieihh/oERbfvRm38XvS/xHAwCgYIKoZIzj0EAwIw
 | 
				
			||||||
 | 
					GjEYMBYGA1UEAxMPSW50ZXJtZWRpYXRlLUNBMCAXDTE2MTAxMTA1MDYwMFoYDzIx
 | 
				
			||||||
 | 
					MTYwOTE3MDUwNjAwWjAUMRIwEAYDVQQDEwlNeSBDbGllbnQwWTATBgcqhkjOPQIB
 | 
				
			||||||
 | 
					BggqhkjOPQMBBwNCAARv6N4R/sjMR65iMFGNLN1GC/vd7WhDW6J4X/iAjkRLLnNb
 | 
				
			||||||
 | 
					KbRG/AtOUZ+7upJ3BWIRKYbOabbQGQe2BbKFiap4o3UwczAOBgNVHQ8BAf8EBAMC
 | 
				
			||||||
 | 
					BaAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQU
 | 
				
			||||||
 | 
					K/pZOWpNcYai6eHFpmJEeFpeQlEwHwYDVR0jBBgwFoAUX6nQlxjfWnP6aM1meO/Q
 | 
				
			||||||
 | 
					a6b3a9kwCgYIKoZIzj0EAwIDSQAwRgIhAIWTKw/sjJITqeuNzJDAKU4xo1zL+xJ5
 | 
				
			||||||
 | 
					MnVCuBwfwDXCAiEAw/1TA+CjPq9JC5ek1ifR0FybTURjeQqYkKpve1dveps=
 | 
				
			||||||
 | 
					-----END CERTIFICATE-----
 | 
				
			||||||
							
								
								
									
										24
									
								
								plugin/pkg/auth/authenticator/request/x509/testdata/client.config.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								plugin/pkg/auth/authenticator/request/x509/testdata/client.config.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					    "signing": {
 | 
				
			||||||
 | 
					        "profiles": {
 | 
				
			||||||
 | 
					            "valid": {
 | 
				
			||||||
 | 
					                "expiry": "876000h",
 | 
				
			||||||
 | 
					                "usages": [
 | 
				
			||||||
 | 
					                    "signing",
 | 
				
			||||||
 | 
					                    "key encipherment",
 | 
				
			||||||
 | 
					                    "client auth"
 | 
				
			||||||
 | 
					                ]
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "expired": {
 | 
				
			||||||
 | 
					                "expiry": "1h",
 | 
				
			||||||
 | 
					                "not_before": "1990-12-31T23:59:00Z",
 | 
				
			||||||
 | 
					                "not_after": "1990-12-31T23:59:00Z",
 | 
				
			||||||
 | 
					                "usages": [
 | 
				
			||||||
 | 
					                    "signing",
 | 
				
			||||||
 | 
					                    "key encipherment",
 | 
				
			||||||
 | 
					                    "client auth"
 | 
				
			||||||
 | 
					                ]
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										3
									
								
								plugin/pkg/auth/authenticator/request/x509/testdata/client.csr.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								plugin/pkg/auth/authenticator/request/x509/testdata/client.csr.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					    "CN": "My Client"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										24
									
								
								plugin/pkg/auth/authenticator/request/x509/testdata/generate.sh
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										24
									
								
								plugin/pkg/auth/authenticator/request/x509/testdata/generate.sh
									
									
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,24 @@
 | 
				
			|||||||
 | 
					#!/usr/bin/env bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Copyright 2016 The Kubernetes Authors.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					# you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					# You may obtain a copy of the License at
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					# distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					# See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					# limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cfssl gencert -initca root.csr.json | cfssljson -bare root
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cfssl gencert -initca intermediate.csr.json | cfssljson -bare intermediate
 | 
				
			||||||
 | 
					cfssl sign -ca root.pem -ca-key root-key.pem -config intermediate.config.json intermediate.csr | cfssljson -bare intermediate
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cfssl gencert -ca intermediate.pem -ca-key intermediate-key.pem -config client.config.json --profile=valid   client.csr.json | cfssljson -bare client-valid
 | 
				
			||||||
 | 
					cfssl gencert -ca intermediate.pem -ca-key intermediate-key.pem -config client.config.json --profile=expired client.csr.json | cfssljson -bare client-expired
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
							
								
								
									
										18
									
								
								plugin/pkg/auth/authenticator/request/x509/testdata/intermediate.config.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								plugin/pkg/auth/authenticator/request/x509/testdata/intermediate.config.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					    "signing": {
 | 
				
			||||||
 | 
					        "default": {
 | 
				
			||||||
 | 
					            "usages": [
 | 
				
			||||||
 | 
					                "digital signature",
 | 
				
			||||||
 | 
					                "cert sign",
 | 
				
			||||||
 | 
					                "crl sign",
 | 
				
			||||||
 | 
					                "signing",
 | 
				
			||||||
 | 
					                "key encipherment",
 | 
				
			||||||
 | 
					                "client auth"
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					            "expiry": "876000h",
 | 
				
			||||||
 | 
					            "ca_constraint": {
 | 
				
			||||||
 | 
					                "is_ca": true
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										6
									
								
								plugin/pkg/auth/authenticator/request/x509/testdata/intermediate.csr.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								plugin/pkg/auth/authenticator/request/x509/testdata/intermediate.csr.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					    "CN": "Intermediate-CA",
 | 
				
			||||||
 | 
					    "ca": {
 | 
				
			||||||
 | 
					        "expiry": "876000h"
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										11
									
								
								plugin/pkg/auth/authenticator/request/x509/testdata/intermediate.pem
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								plugin/pkg/auth/authenticator/request/x509/testdata/intermediate.pem
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					-----BEGIN CERTIFICATE-----
 | 
				
			||||||
 | 
					MIIBqDCCAU6gAwIBAgIUfqZtjoFgczZ+oQZbEC/BDSS2J6wwCgYIKoZIzj0EAwIw
 | 
				
			||||||
 | 
					EjEQMA4GA1UEAxMHUm9vdC1DQTAgFw0xNjEwMTEwNTA2MDBaGA8yMTE2MDkxNzA1
 | 
				
			||||||
 | 
					MDYwMFowGjEYMBYGA1UEAxMPSW50ZXJtZWRpYXRlLUNBMFkwEwYHKoZIzj0CAQYI
 | 
				
			||||||
 | 
					KoZIzj0DAQcDQgAEyWHEMMCctJg8Xa5YWLqaCPbk3MjB+uvXac42JM9pj4k9jedD
 | 
				
			||||||
 | 
					kpUJRkWIPzgJI8Zk/3cSzluUTixP6JBSDKtwwaN4MHYwDgYDVR0PAQH/BAQDAgGm
 | 
				
			||||||
 | 
					MBMGA1UdJQQMMAoGCCsGAQUFBwMCMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE
 | 
				
			||||||
 | 
					FF+p0JcY31pz+mjNZnjv0Gum92vZMB8GA1UdIwQYMBaAFB7P6+i4/pfNjqZgJv/b
 | 
				
			||||||
 | 
					dgA7Fe4tMAoGCCqGSM49BAMCA0gAMEUCIQCTT1YWQZaAqfQ2oBxzOkJE2BqLFxhz
 | 
				
			||||||
 | 
					3smQlrZ5gCHddwIgcvT7puhYOzAgcvMn9+SZ1JOyZ7edODjshCVCRnuHK2c=
 | 
				
			||||||
 | 
					-----END CERTIFICATE-----
 | 
				
			||||||
							
								
								
									
										6
									
								
								plugin/pkg/auth/authenticator/request/x509/testdata/root.csr.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								plugin/pkg/auth/authenticator/request/x509/testdata/root.csr.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					    "CN": "Root-CA",
 | 
				
			||||||
 | 
					    "ca": {
 | 
				
			||||||
 | 
					        "expiry": "876000h"
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										11
									
								
								plugin/pkg/auth/authenticator/request/x509/testdata/root.pem
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								plugin/pkg/auth/authenticator/request/x509/testdata/root.pem
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					-----BEGIN CERTIFICATE-----
 | 
				
			||||||
 | 
					MIIBizCCATGgAwIBAgIUH4plk9qwD61FVXgiOTngFU5FeSkwCgYIKoZIzj0EAwIw
 | 
				
			||||||
 | 
					EjEQMA4GA1UEAxMHUm9vdC1DQTAgFw0xNjEwMTEwNTA2MDBaGA8yMTE2MDkxNzA1
 | 
				
			||||||
 | 
					MDYwMFowEjEQMA4GA1UEAxMHUm9vdC1DQTBZMBMGByqGSM49AgEGCCqGSM49AwEH
 | 
				
			||||||
 | 
					A0IABI2CsrAnMGT8P2VGU2MLo5pv86Z74kcV9hgkLJUkSaeNyc1s89w7X5V2wvwu
 | 
				
			||||||
 | 
					iWEJRGm5RoZJausmyZLZEoKEVXejYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB
 | 
				
			||||||
 | 
					Af8EBTADAQH/MB0GA1UdDgQWBBQez+vouP6XzY6mYCb/23YAOxXuLTAfBgNVHSME
 | 
				
			||||||
 | 
					GDAWgBQez+vouP6XzY6mYCb/23YAOxXuLTAKBggqhkjOPQQDAgNIADBFAiBGclts
 | 
				
			||||||
 | 
					vJRM+QMVoV/1L9b+hvhgLIp/OupUFsSOReefIwIhALY06hBklyh8eFwuBtyX2VcE
 | 
				
			||||||
 | 
					8xlVn4/5idUvc3Xv2h9s
 | 
				
			||||||
 | 
					-----END CERTIFICATE-----
 | 
				
			||||||
@@ -52,18 +52,25 @@ func New(opts x509.VerifyOptions, user UserConversion) *Authenticator {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// AuthenticateRequest authenticates the request using presented client certificates
 | 
					// AuthenticateRequest authenticates the request using presented client certificates
 | 
				
			||||||
func (a *Authenticator) AuthenticateRequest(req *http.Request) (user.Info, bool, error) {
 | 
					func (a *Authenticator) AuthenticateRequest(req *http.Request) (user.Info, bool, error) {
 | 
				
			||||||
	if req.TLS == nil {
 | 
						if req.TLS == nil || len(req.TLS.PeerCertificates) == 0 {
 | 
				
			||||||
		return nil, false, nil
 | 
							return nil, false, nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var errlist []error
 | 
						// Use intermediates, if provided
 | 
				
			||||||
	for _, cert := range req.TLS.PeerCertificates {
 | 
						optsCopy := a.opts
 | 
				
			||||||
		chains, err := cert.Verify(a.opts)
 | 
						if optsCopy.Intermediates == nil && len(req.TLS.PeerCertificates) > 1 {
 | 
				
			||||||
		if err != nil {
 | 
							optsCopy.Intermediates = x509.NewCertPool()
 | 
				
			||||||
			errlist = append(errlist, err)
 | 
							for _, intermediate := range req.TLS.PeerCertificates[1:] {
 | 
				
			||||||
			continue
 | 
								optsCopy.Intermediates.AddCert(intermediate)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						chains, err := req.TLS.PeerCertificates[0].Verify(optsCopy)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, false, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var errlist []error
 | 
				
			||||||
	for _, chain := range chains {
 | 
						for _, chain := range chains {
 | 
				
			||||||
		user, ok, err := a.user.User(chain)
 | 
							user, ok, err := a.user.User(chain)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
@@ -75,7 +82,6 @@ func (a *Authenticator) AuthenticateRequest(req *http.Request) (user.Info, bool,
 | 
				
			|||||||
			return user, ok, err
 | 
								return user, ok, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil, false, utilerrors.NewAggregate(errlist)
 | 
						return nil, false, utilerrors.NewAggregate(errlist)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,6 +21,7 @@ import (
 | 
				
			|||||||
	"crypto/x509"
 | 
						"crypto/x509"
 | 
				
			||||||
	"encoding/pem"
 | 
						"encoding/pem"
 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
 | 
						"io/ioutil"
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
	"reflect"
 | 
						"reflect"
 | 
				
			||||||
	"sort"
 | 
						"sort"
 | 
				
			||||||
@@ -507,6 +508,10 @@ PKJQCs0CM0zkesktuLi/gFpuB0nEwyOgLg==
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestX509(t *testing.T) {
 | 
					func TestX509(t *testing.T) {
 | 
				
			||||||
 | 
						multilevelOpts := DefaultVerifyOptions()
 | 
				
			||||||
 | 
						multilevelOpts.Roots = x509.NewCertPool()
 | 
				
			||||||
 | 
						multilevelOpts.Roots.AddCert(getCertsFromFile(t, "root")[0])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	testCases := map[string]struct {
 | 
						testCases := map[string]struct {
 | 
				
			||||||
		Insecure bool
 | 
							Insecure bool
 | 
				
			||||||
		Certs    []*x509.Certificate
 | 
							Certs    []*x509.Certificate
 | 
				
			||||||
@@ -659,6 +664,24 @@ func TestX509(t *testing.T) {
 | 
				
			|||||||
			ExpectOK:  false,
 | 
								ExpectOK:  false,
 | 
				
			||||||
			ExpectErr: true,
 | 
								ExpectErr: true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							"multi-level, valid": {
 | 
				
			||||||
 | 
								Opts:  multilevelOpts,
 | 
				
			||||||
 | 
								Certs: getCertsFromFile(t, "client-valid", "intermediate"),
 | 
				
			||||||
 | 
								User:  CommonNameUserConversion,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								ExpectUserName: "My Client",
 | 
				
			||||||
 | 
								ExpectOK:       true,
 | 
				
			||||||
 | 
								ExpectErr:      false,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							"multi-level, expired": {
 | 
				
			||||||
 | 
								Opts:  multilevelOpts,
 | 
				
			||||||
 | 
								Certs: getCertsFromFile(t, "client-expired", "intermediate"),
 | 
				
			||||||
 | 
								User:  CommonNameUserConversion,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								ExpectOK:  false,
 | 
				
			||||||
 | 
								ExpectErr: true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for k, testCase := range testCases {
 | 
						for k, testCase := range testCases {
 | 
				
			||||||
@@ -718,6 +741,19 @@ func getRootCertPoolFor(t *testing.T, certs ...string) *x509.CertPool {
 | 
				
			|||||||
	return pool
 | 
						return pool
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func getCertsFromFile(t *testing.T, names ...string) []*x509.Certificate {
 | 
				
			||||||
 | 
						certs := []*x509.Certificate{}
 | 
				
			||||||
 | 
						for _, name := range names {
 | 
				
			||||||
 | 
							filename := "testdata/" + name + ".pem"
 | 
				
			||||||
 | 
							data, err := ioutil.ReadFile(filename)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								t.Fatalf("error reading %s: %v", filename, err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							certs = append(certs, getCert(t, string(data)))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return certs
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func getCert(t *testing.T, pemData string) *x509.Certificate {
 | 
					func getCert(t *testing.T, pemData string) *x509.Certificate {
 | 
				
			||||||
	pemBlock, _ := pem.Decode([]byte(pemData))
 | 
						pemBlock, _ := pem.Decode([]byte(pemData))
 | 
				
			||||||
	cert, err := x509.ParseCertificate(pemBlock.Bytes)
 | 
						cert, err := x509.ParseCertificate(pemBlock.Bytes)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user