github.com/aporeto-inc/trireme-lib@v10.358.0+incompatible/controller/internal/enforcer/envoyauthorizer/envoyproxy/sds_server.go (about) 1 package envoyproxy 2 3 import ( 4 "bytes" 5 "crypto/tls" 6 "crypto/x509" 7 "encoding/pem" 8 "fmt" 9 "net" 10 "sync" 11 "time" 12 13 "context" 14 15 "go.aporeto.io/enforcerd/trireme-lib/controller/pkg/secrets" 16 "go.aporeto.io/enforcerd/trireme-lib/policy" 17 "go.aporeto.io/enforcerd/trireme-lib/utils/cache" 18 "go.uber.org/zap" 19 "google.golang.org/grpc" 20 21 v2 "github.com/envoyproxy/go-control-plane/envoy/api/v2" 22 envoy_api_v2_auth "github.com/envoyproxy/go-control-plane/envoy/api/v2/auth" 23 envoy_api_v2_core "github.com/envoyproxy/go-control-plane/envoy/api/v2/core" 24 sds "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v2" 25 26 "github.com/golang/protobuf/ptypes" 27 //"github.com/gogo/protobuf/types" 28 "google.golang.org/grpc/metadata" 29 ) 30 31 const ( 32 // SdsSocketpath is the socket path on which the envoy will talk to the remoteEnforcer. 33 //SdsSocketpath = "@aporeto_envoy_sds" 34 SdsSocketpath = "127.0.0.1:2999" 35 //SdsSocketpath = "/var/run/sds/uds_path" 36 typeCertificate = "CERTIFICATE" 37 ) 38 39 // Options to create a SDS server to task to envoy 40 type Options struct { 41 SocketPath string 42 } 43 44 // sdsCerts is the structure will pass the upstream certs downwards. 45 type sdsCerts struct { 46 key string 47 cert string 48 caPool *x509.CertPool 49 } 50 51 // SdsDiscoveryStream is the same as the sds.SecretDiscoveryService_StreamSecretsServer 52 type SdsDiscoveryStream interface { 53 Send(*v2.DiscoveryResponse) error 54 Recv() (*v2.DiscoveryRequest, error) 55 grpc.ServerStream 56 } 57 58 var _ sds.SecretDiscoveryServiceServer = &SdsServer{} 59 60 // SdsServer to talk with envoy for sds. 61 type SdsServer struct { 62 sdsGrpcServer *grpc.Server 63 sdsGrpcListener net.Listener 64 65 errCh chan error 66 puInfo *policy.PUInfo 67 cert *tls.Certificate 68 ca *x509.CertPool 69 keyPEM string 70 certPEM string 71 secrets secrets.Secrets 72 sync.RWMutex 73 // conncache is a cache of the sdsConnection, here the key is the connectionID and val is the secret. 74 conncache cache.DataStore 75 // updCertsChannel is used whenever there is a cert-update/Enfore 76 updCertsChannel chan sdsCerts 77 connMap map[string]bool 78 } 79 80 type secretItem struct { 81 CertificateChain []byte 82 PrivateKey []byte 83 84 RootCert []byte 85 86 // RootCertOwnedByCompoundSecret is true if this SecretItem was created by a 87 // K8S secret having both server cert/key and client ca and should be deleted 88 // with the secret. 89 RootCertOwnedByCompoundSecret bool 90 91 // ResourceName passed from envoy SDS discovery request. 92 // "ROOTCA" for root cert request, "default" for key/cert request. 93 ResourceName string 94 95 // Credential token passed from envoy, caClient uses this token to send 96 // CSR to CA to sign certificate. 97 Token string 98 99 // Version is used(together with token and ResourceName) to identify discovery request from 100 // envoy which is used only for confirm purpose. 101 Version string 102 103 CreatedTime time.Time 104 105 ExpireTime time.Time 106 } 107 108 // clientConn is ID for the connection between client and SDS server. 109 type clientConn struct { 110 clientID string 111 // the TLS cert information cached for this particular connection 112 secret *secretItem 113 114 // connectionID is the ID for each new request, make it a combo of nodeID+counter. 115 connectionID string 116 stream SdsDiscoveryStream 117 } 118 119 // NewSdsServer creates a instance of a server. 120 func NewSdsServer(contextID string, puInfo *policy.PUInfo, caPool *x509.CertPool, secrets secrets.Secrets) (*SdsServer, error) { 121 if puInfo == nil { 122 zap.L().Error("SDS Server: puInfo NIL ") 123 return nil, fmt.Errorf("the puinfo cannot be nil") 124 } 125 126 sdsOptions := &Options{SocketPath: SdsSocketpath} 127 sdsServer := &SdsServer{ 128 puInfo: puInfo, 129 ca: caPool, 130 errCh: make(chan error), 131 secrets: secrets, 132 conncache: cache.NewCache("servers"), 133 updCertsChannel: make(chan sdsCerts), 134 connMap: make(map[string]bool), 135 } 136 if err := sdsServer.CreateSdsService(sdsOptions); err != nil { 137 zap.L().Error("SDS Server:Error while starting the envoy sds server.") 138 return nil, err 139 } 140 zap.L().Debug("SDS Server: SDS start success", zap.String("pu", puInfo.ContextID)) 141 return sdsServer, nil 142 } 143 144 // CreateSdsService does the following 145 // 1. create grpc server. 146 // 2. create a listener on the Unix Domain Socket. 147 // 3. 148 func (s *SdsServer) CreateSdsService(options *Options) error { // nolint: unparam 149 s.sdsGrpcServer = grpc.NewServer() 150 s.register(s.sdsGrpcServer) 151 152 addr, err := net.ResolveTCPAddr("tcp", options.SocketPath) 153 if err != nil { 154 return err 155 } 156 nl, err := net.ListenTCP("tcp", addr) 157 if err != nil { 158 return err 159 } 160 // if err := os.Remove(options.SocketPath); err != nil && !os.IsNotExist(err) { 161 // zap.L().Error("SDS Server: envoy-reireme, failed to remove the udspath", zap.Error(err)) 162 // return err 163 // } 164 // zap.L().Debug("SDS Server: Start listening on UDS path", zap.Any("socketPath", options.SocketPath)) 165 // addr, _ := net.ResolveUnixAddr("unix", options.SocketPath) 166 167 // sdsGrpcListener, err := net.ListenUnix("unix", addr) 168 // if err != nil { 169 // zap.L().Error("SDS Server:cannot listen on the socketpath", zap.Error(err)) 170 // return err 171 // } 172 // //make sure the socket path can be accessed. 173 // if _, err := os.Stat(options.SocketPath); err != nil { 174 // zap.L().Error("SDS Server: SDS uds file doesn't exist", zap.String("socketPath:", options.SocketPath)) 175 // return fmt.Errorf("sds uds file %q doesn't exist", options.SocketPath) 176 // } 177 // if err := os.Chmod(options.SocketPath, 0666); err != nil { 178 // zap.L().Error("SDS Server: Failed to update permission", zap.String("socketPath:", options.SocketPath)) 179 // return fmt.Errorf("failed to update %q permission", options.SocketPath) 180 // } 181 s.sdsGrpcListener = nl 182 183 zap.L().Debug("SDS Server: run the grpc server at", zap.Any("addr", s.sdsGrpcListener.Addr())) 184 s.Run() 185 return nil 186 } 187 188 // Run starts the sdsGrpcServer to serve 189 func (s *SdsServer) Run() { 190 go func() { 191 if s.sdsGrpcListener != nil { 192 if err := s.sdsGrpcServer.Serve(s.sdsGrpcListener); err != nil { 193 zap.L().Error("SDS Server: Error while serve", zap.Error(err)) 194 s.errCh <- err 195 } 196 } 197 zap.L().Error("SDS Server: the listener is nil, cannot start the SDS server for", zap.String("puID", s.puInfo.ContextID)) 198 }() 199 } 200 201 // Stop stops all the listeners and the grpc servers. 202 func (s *SdsServer) Stop() { 203 if s.sdsGrpcListener != nil { 204 s.sdsGrpcListener.Close() // nolint 205 } 206 if s.sdsGrpcServer != nil { 207 s.sdsGrpcServer.Stop() 208 } 209 } 210 211 // GracefulStop calls the function with the same name on the backing gRPC server 212 func (s *SdsServer) GracefulStop() { 213 s.sdsGrpcServer.GracefulStop() 214 } 215 216 // register adds the SDS handle to the grpc server 217 func (s *SdsServer) register(sdsGrpcServer *grpc.Server) { 218 zap.L().Debug("SDS Server: envoy-trireme registering the secret discovery") 219 sds.RegisterSecretDiscoveryServiceServer(sdsGrpcServer, s) 220 } 221 222 // UpdateSecrets updates the secrets 223 // Whenever the Envoy makes a request for certificate, the certs and keys are fetched from 224 // the Proxy. 225 func (s *SdsServer) UpdateSecrets(cert *tls.Certificate, caPool *x509.CertPool, secrets secrets.Secrets, certPEM, keyPEM string) { 226 s.Lock() 227 defer s.Unlock() 228 229 s.cert = cert 230 s.ca = caPool 231 //s.secrets = secrets 232 s.certPEM = certPEM 233 s.keyPEM = keyPEM 234 s.updCertsChannel <- sdsCerts{key: keyPEM, cert: certPEM, caPool: caPool} 235 } 236 237 // now implement the interfaces of the SDS grpc server. 238 // type SecretDiscoveryServiceServer interface { 239 // DeltaSecrets(SecretDiscoveryService_DeltaSecretsServer) error 240 // StreamSecrets(SecretDiscoveryService_StreamSecretsServer) error 241 // FetchSecrets(context.Context, *v2.DiscoveryRequest) (*v2.DiscoveryResponse, error) 242 // } 243 244 // DeltaSecrets checks for the delta and sends the changes. 245 func (s *SdsServer) DeltaSecrets(stream sds.SecretDiscoveryService_DeltaSecretsServer) error { 246 return nil 247 } 248 249 func startStreaming(stream SdsDiscoveryStream, discoveryReqCh chan *v2.DiscoveryRequest) { 250 defer close(discoveryReqCh) 251 for { 252 req, err := stream.Recv() 253 if err != nil { 254 zap.L().Error("SDS Server: Connection terminated with err", zap.Error(err)) 255 return 256 } 257 discoveryReqCh <- req 258 } 259 } 260 261 // StreamSecrets is the function invoked by the envoy in-order to pull the certs, this also sends the response back to the envoy. 262 // It does the following: 263 // 1. create a receiver thread to stream the requests. 264 // 2. parse the discovery request. 265 // 3. track the request. 266 // 4. call the Aporeto api to generate the secret 267 func (s *SdsServer) StreamSecrets(stream sds.SecretDiscoveryService_StreamSecretsServer) error { 268 ctx := stream.Context() 269 token := "" 270 metadata, ok := metadata.FromIncomingContext(ctx) 271 if !ok { 272 return fmt.Errorf("unable to get metadata from incoming context") 273 } 274 if h, ok := metadata["authorization"]; ok { 275 if len(h) != 1 { 276 return fmt.Errorf("credential token from %q must have 1 value in gRPC metadata but got %d", "authorization", len(h)) 277 } 278 token = h[0] 279 } 280 zap.L().Debug("SDS Server: IN stream secrets, token", zap.String("token", token)) 281 282 // create new connection 283 conn := &clientConn{} 284 conn.stream = stream 285 discoveryReqCh := make(chan *v2.DiscoveryRequest, 1) 286 go startStreaming(stream, discoveryReqCh) 287 288 for { 289 // wait for the receiver thread to stream the request and send it to us over here. 290 select { 291 case req, ok := <-discoveryReqCh: 292 // if req == nil { 293 // zap.L().Warn("SDS Server: The request is nil") 294 // continue 295 // } 296 // Now check the following: 297 // 1. Return if stream is closed. 298 // 2. Return if its invalid request. 299 if !ok { 300 zap.L().Error("SDS Server: Receiver channel closed, which means the Receiver stream is closed") 301 return fmt.Errorf("Receiver closed the channel") 302 } 303 // then check for the req.Node 304 if req.Node == nil { 305 zap.L().Error("Invalid discovery request with no node") 306 return fmt.Errorf("invalid discovery request with no node") 307 } 308 if req.ErrorDetail != nil { 309 zap.L().Error("SDS Server: ERROR from envoy for processing the resource", zap.String("error", req.GetErrorDetail().String())) 310 continue 311 } 312 313 // now according to the Istio pilot SDS secret config we have 2 configs, this configs are pushed to envoy through Istio. 314 // 1. SDSDefaultResourceName is the default name in sdsconfig, used for fetching normal key/cert. 315 // 2. SDSRootResourceName is the sdsconfig name for root CA, used for fetching root cert. 316 // therefore from the above we receive 2 requests, 1 for default and 2 for the ROOTCA 317 318 // now check for the resourcename, it should atleast have one, else continue and stream the next request. 319 // according to the definition this could be empty. 320 if len(req.ResourceNames) == 0 { 321 continue 322 } 323 if len(req.ResourceNames) > 1 { 324 return fmt.Errorf("SDS Server: invalid resourceNames, greater than one") 325 } 326 resourceName := req.ResourceNames[0] 327 conn.clientID = req.Node.GetId() 328 //if len(conn.connectionID) == 0 { 329 conn.connectionID = createConnID(conn.clientID, resourceName) 330 331 // if this is not the 1st request and if the secret is already present then dont proceed as this is a ACK according to the XDS protocol. 332 if req.VersionInfo != "" && s.checkSecretPresent(conn.connectionID, req, token) { 333 zap.L().Warn("SDS Server: got a ACK from envoy", zap.String("connectionID", conn.connectionID), zap.String("resourceName", resourceName), zap.String("version", req.VersionInfo)) 334 continue 335 } 336 secret := s.generateSecret(req, token) 337 if secret == nil { 338 zap.L().Error("SDS Server: the Certs cannot be served so return nil") 339 return fmt.Errorf("the aporeto SDS server cannot generate server, the certs are nil") 340 } 341 conn.secret = secret 342 s.conncache.AddOrUpdate(conn.connectionID, conn) 343 344 resp := &v2.DiscoveryResponse{ 345 TypeUrl: "type.googleapis.com/envoy.api.v2.auth.Secret", 346 VersionInfo: secret.Version, 347 Nonce: secret.Version, 348 } 349 retSecret := &envoy_api_v2_auth.Secret{ 350 Name: secret.ResourceName, 351 } 352 if secret.RootCert != nil { 353 retSecret.Type = getRootCert(secret) 354 } else { 355 retSecret.Type = getTLScerts(secret) 356 } 357 endSecret, err := ptypes.MarshalAny(retSecret) 358 if err != nil { 359 zap.L().Error("SDS Server: Cannot marshall the secret", zap.Error(err)) 360 continue 361 } 362 resp.Resources = append(resp.Resources, endSecret) 363 if err = stream.Send(resp); err != nil { 364 zap.L().Error("SDS Server: Failed to send the resp cert", zap.Error(err)) 365 return err 366 } 367 if secret.RootCert != nil { 368 zap.L().Debug("SDS Server: Successfully sent root cert", zap.String("rootCA", string(secret.RootCert))) 369 } else { 370 zap.L().Debug("SDS Server: Successfully sent default cert", zap.String("default cert", string(secret.CertificateChain))) 371 } 372 case updateCerts := <-s.updCertsChannel: 373 // 1st check if the connection is present 374 375 if _, err := s.conncache.Get(conn.connectionID); err != nil { 376 zap.L().Warn("SDS server: updCertsChannel, no connID found in cache,", zap.String("connID", conn.connectionID)) 377 continue 378 } 379 fmt.Println("connID found now send certs") 380 if updateCerts.key != "" && updateCerts.cert != "" { 381 if err := s.sendUpdatedCerts(updateCerts, conn); err != nil { 382 zap.L().Error("SDS Server: send updated certs failed", zap.Error(err)) 383 } 384 } 385 } 386 } 387 388 } 389 390 func (s *SdsServer) sendUpdatedCerts(apoSecret sdsCerts, conn *clientConn) error { 391 var err error 392 pemCert := []byte{} // nolint 393 t := time.Now() 394 395 if apoSecret.key != "" && apoSecret.cert != "" { 396 caPEM := s.secrets.CertAuthority() 397 398 pemCert, err = buildCertChain([]byte(apoSecret.cert), caPEM) 399 if err != nil { 400 zap.L().Error("SDS Server: Cannot build the cert chain") 401 return fmt.Errorf("SDS Server: Cannot build the cert chain") 402 } 403 404 resp := &v2.DiscoveryResponse{ 405 TypeUrl: "type.googleapis.com/envoy.api.v2.auth.Secret", 406 VersionInfo: t.String(), 407 Nonce: t.String(), 408 } 409 retSecret := &envoy_api_v2_auth.Secret{ 410 Name: "default", 411 } 412 413 retSecret.Type = &envoy_api_v2_auth.Secret_TlsCertificate{ 414 TlsCertificate: &envoy_api_v2_auth.TlsCertificate{ 415 CertificateChain: &envoy_api_v2_core.DataSource{ 416 Specifier: &envoy_api_v2_core.DataSource_InlineBytes{ 417 InlineBytes: pemCert, 418 }, 419 }, 420 PrivateKey: &envoy_api_v2_core.DataSource{ 421 Specifier: &envoy_api_v2_core.DataSource_InlineBytes{ 422 InlineBytes: []byte(apoSecret.key), 423 }, 424 }, 425 }, 426 } 427 428 endSecret, err := ptypes.MarshalAny(retSecret) 429 if err != nil { 430 zap.L().Error("SDS Server: Cannot marshall the secret") 431 return fmt.Errorf("SDS Server: Cannot marshall the secret") 432 } 433 434 resp.Resources = append(resp.Resources, endSecret) 435 if err = conn.stream.Send(resp); err != nil { 436 zap.L().Error("SDS Server: Failed to send the resp cert") 437 return err 438 } 439 440 } 441 return nil 442 } 443 444 func (s *SdsServer) checkSecretPresent(connID string, req *v2.DiscoveryRequest, token string) bool { 445 val, err := s.conncache.Get(connID) 446 if err != nil { 447 return false 448 } 449 e := val.(*clientConn) 450 return e.secret.ResourceName == req.ResourceNames[0] && e.secret.Token == token && e.secret.Version == req.VersionInfo 451 } 452 453 func createConnID(clientID, resourceName string) string { 454 temp := clientID + resourceName 455 zap.L().Debug("SDS Server: generated a unique ID", zap.String("connID", temp), zap.String("resource", resourceName)) 456 return temp 457 } 458 459 // FetchSecrets gets the discovery request and call the Aporeto backend to fetch the certs. 460 // 1. parse the discovery request. 461 // 2. track the request. 462 // 3. call the Aporeto api to generate the secret 463 func (s *SdsServer) FetchSecrets(ctx context.Context, req *v2.DiscoveryRequest) (*v2.DiscoveryResponse, error) { 464 token := "" 465 metadata, ok := metadata.FromIncomingContext(ctx) 466 if !ok { 467 return nil, fmt.Errorf("unable to get metadata from incoming context") 468 } 469 if h, ok := metadata["authorization"]; ok { 470 if len(h) != 1 { 471 return nil, fmt.Errorf("credential token from %q must have 1 value in gRPC metadata but got %d", "authorization", len(h)) 472 } 473 token = h[0] 474 } 475 zap.L().Info("SDS Server: IN stream secrets, token", zap.String("token", token)) 476 secret := s.generateSecret(req, token) 477 478 resp := &v2.DiscoveryResponse{ 479 TypeUrl: "type.googleapis.com/envoy.api.v2.auth.Secret", 480 } 481 retSecret := &envoy_api_v2_auth.Secret{ 482 Name: secret.ResourceName, 483 } 484 if secret.RootCert != nil { 485 retSecret.Type = getRootCert(secret) 486 } else { 487 retSecret.Type = getTLScerts(secret) 488 } 489 endSecret, err := ptypes.MarshalAny(retSecret) 490 if err != nil { 491 zap.L().Error("SDS Server: Cannot marshall the secret") 492 return nil, err 493 } 494 resp.Resources = append(resp.Resources, endSecret) 495 496 if secret.RootCert != nil { 497 zap.L().Debug("SDS Server: Successfully sent root cert", zap.Any("rootCA", string(secret.RootCert))) 498 } else { 499 zap.L().Debug("SDS Server: Successfully sent default cert", zap.Any("default cert", string(secret.CertificateChain))) 500 } 501 return resp, nil 502 } 503 504 // generateSecret is the call which talks to the metadata API to fetch the certs. 505 func (s *SdsServer) generateSecret(req *v2.DiscoveryRequest, token string) *secretItem { 506 507 var err error 508 var pemCert []byte 509 t := time.Now() 510 var expTime time.Time 511 512 if s.puInfo.Policy == nil { 513 zap.L().Error("SDS Server: The policy is nil, Policy cannot be nil.") 514 } 515 // now fetch the certificates for the PU/Service. 516 certPEM, keyPEM, _ := s.puInfo.Policy.ServiceCertificates() 517 if certPEM == "" || keyPEM == "" { 518 zap.L().Error("SDS Server: the certs are empty") 519 return nil 520 } 521 522 caPEM := s.secrets.CertAuthority() 523 if req.ResourceNames[0] == "default" { 524 525 expTime, _ = getExpTimeFromCert([]byte(certPEM)) 526 pemCert, _ = buildCertChain([]byte(certPEM), caPEM) 527 if err != nil { 528 zap.L().Error("SDS Server: Cannot build the cert chain") 529 return nil 530 } 531 532 } else { 533 534 expTime, _ = getExpTimeFromCert(caPEM) 535 pemCert, err = getTopRootCa(caPEM) 536 if err != nil { 537 zap.L().Error("SDS Server: Cannot build the Root cert chain") 538 } 539 } 540 if err != nil { 541 zap.L().Error("SDS Server: cannot get exp time", zap.Error(err)) 542 return nil 543 } 544 if req.ResourceNames[0] == "default" { 545 return &secretItem{ 546 CertificateChain: pemCert, 547 PrivateKey: []byte(keyPEM), 548 //PrivateKey: []byte(keyPEMdebug), 549 ResourceName: req.ResourceNames[0], 550 Token: token, 551 CreatedTime: t, 552 ExpireTime: expTime, 553 Version: t.String(), 554 } 555 } 556 557 return &secretItem{ 558 RootCert: pemCert, 559 ResourceName: req.ResourceNames[0], 560 Token: token, 561 CreatedTime: t, 562 ExpireTime: expTime, 563 Version: t.String(), 564 } 565 566 } 567 568 func buildCertChain(certPEM, caPEM []byte) ([]byte, error) { 569 zap.L().Debug("SDS Server: BEFORE in buildCertChain certPEM", zap.String("certPEM", string(certPEM)), zap.String("caPEM", string(caPEM))) 570 certChain := []*x509.Certificate{} 571 //certPEMBlock := caPEM 572 clientPEMBlock := certPEM 573 derBlock, _ := pem.Decode(clientPEMBlock) 574 if derBlock != nil { 575 if derBlock.Type == typeCertificate { 576 cert, err := x509.ParseCertificate(derBlock.Bytes) 577 if err != nil { 578 return nil, err 579 } 580 certChain = append(certChain, cert) 581 } else { 582 return nil, fmt.Errorf("invalid pem block type: %s", derBlock.Type) 583 } 584 } 585 var certDERBlock *pem.Block 586 for { 587 certDERBlock, caPEM = pem.Decode(caPEM) 588 if certDERBlock == nil { 589 break 590 } 591 if certDERBlock.Type == typeCertificate { 592 cert, err := x509.ParseCertificate(certDERBlock.Bytes) 593 if err != nil { 594 return nil, err 595 } 596 certChain = append(certChain, cert) 597 } else { 598 return nil, fmt.Errorf("invalid pem block type: %s", certDERBlock.Type) 599 } 600 } 601 by, _ := x509CertChainToPem(certChain) 602 zap.L().Debug("SDS Server: After building the cert chain", zap.String("certChain", string(by))) 603 return x509CertChainToPem(certChain) 604 } 605 606 // x509CertToPem converts x509 to byte. 607 func x509CertToPem(cert *x509.Certificate) ([]byte, error) { 608 var pemBytes bytes.Buffer 609 if err := pem.Encode(&pemBytes, &pem.Block{Type: typeCertificate, Bytes: cert.Raw}); err != nil { 610 return nil, err 611 } 612 return pemBytes.Bytes(), nil 613 } 614 615 // x509CertChainToPem converts chain of x509 certs to byte. 616 func x509CertChainToPem(certChain []*x509.Certificate) ([]byte, error) { 617 var pemBytes bytes.Buffer 618 for _, cert := range certChain { 619 if err := pem.Encode(&pemBytes, &pem.Block{Type: typeCertificate, Bytes: cert.Raw}); err != nil { 620 return nil, err 621 } 622 } 623 return pemBytes.Bytes(), nil 624 } 625 626 // getTopRootCa get the top root CA 627 func getTopRootCa(certPEMBlock []byte) ([]byte, error) { 628 zap.L().Debug("SDS Server: BEFORE root cert", zap.String("root_cert", string(certPEMBlock))) 629 //rootCert := []*x509.Certificate{} 630 var certChain tls.Certificate 631 //certPEMBlock := []byte(rootcaBundle) 632 var certDERBlock *pem.Block 633 for { 634 certDERBlock, certPEMBlock = pem.Decode(certPEMBlock) 635 if certDERBlock == nil { 636 break 637 } 638 if certDERBlock.Type == typeCertificate { 639 certChain.Certificate = append(certChain.Certificate, certDERBlock.Bytes) 640 } 641 } 642 zap.L().Debug("SDS Server: the root ca", zap.String("cert", string(certChain.Certificate[len(certChain.Certificate)-1]))) 643 x509Cert, err := x509.ParseCertificate(certChain.Certificate[len(certChain.Certificate)-1]) 644 if err != nil { 645 panic(err) 646 } 647 by, _ := x509CertToPem(x509Cert) 648 zap.L().Debug("SDS Server: After building the cert chain", zap.String("rootCert", string(by))) 649 return x509CertToPem(x509Cert) 650 } 651 652 // getExpTimeFromCert gets the exp time from the cert, assumning the cert is in pem encoded. 653 func getExpTimeFromCert(cert []byte) (time.Time, error) { 654 block, _ := pem.Decode(cert) 655 if block == nil { 656 zap.L().Error("getExpTimeFromCert: error while pem decode") 657 return time.Time{}, fmt.Errorf("Cannot decode the pem certs") 658 } 659 x509Cert, err := x509.ParseCertificate(block.Bytes) 660 if err != nil { 661 zap.L().Error("failed to parse the certs", zap.Error(err)) 662 return time.Time{}, err 663 } 664 return x509Cert.NotAfter, nil 665 } 666 667 func getRootCert(secret *secretItem) *envoy_api_v2_auth.Secret_ValidationContext { 668 return &envoy_api_v2_auth.Secret_ValidationContext{ 669 ValidationContext: &envoy_api_v2_auth.CertificateValidationContext{ 670 TrustedCa: &envoy_api_v2_core.DataSource{ 671 Specifier: &envoy_api_v2_core.DataSource_InlineBytes{ 672 InlineBytes: secret.RootCert, 673 }, 674 }, 675 }, 676 } 677 } 678 679 func getTLScerts(secret *secretItem) *envoy_api_v2_auth.Secret_TlsCertificate { 680 return &envoy_api_v2_auth.Secret_TlsCertificate{ 681 TlsCertificate: &envoy_api_v2_auth.TlsCertificate{ 682 CertificateChain: &envoy_api_v2_core.DataSource{ 683 Specifier: &envoy_api_v2_core.DataSource_InlineBytes{ 684 InlineBytes: secret.CertificateChain, 685 }, 686 }, 687 PrivateKey: &envoy_api_v2_core.DataSource{ 688 Specifier: &envoy_api_v2_core.DataSource_InlineBytes{ 689 InlineBytes: secret.PrivateKey, 690 }, 691 }, 692 }, 693 } 694 }