github.com/hashicorp/vault/sdk@v0.13.0/plugin/pb/translation.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 package pb 5 6 import ( 7 "crypto/tls" 8 "crypto/x509" 9 "encoding/json" 10 "errors" 11 "time" 12 13 "github.com/golang/protobuf/ptypes" 14 "github.com/hashicorp/go-secure-stdlib/parseutil" 15 "github.com/hashicorp/vault/sdk/helper/errutil" 16 "github.com/hashicorp/vault/sdk/helper/wrapping" 17 "github.com/hashicorp/vault/sdk/logical" 18 ) 19 20 const ( 21 ErrTypeUnknown uint32 = iota 22 ErrTypeUserError 23 ErrTypeInternalError 24 ErrTypeCodedError 25 ErrTypeStatusBadRequest 26 ErrTypeUnsupportedOperation 27 ErrTypeUnsupportedPath 28 ErrTypeInvalidRequest 29 ErrTypePermissionDenied 30 ErrTypeMultiAuthzPending 31 ErrTypeUnrecoverable 32 ) 33 34 func ProtoErrToErr(e *ProtoError) error { 35 if e == nil { 36 return nil 37 } 38 39 var err error 40 switch e.ErrType { 41 case ErrTypeUnknown: 42 err = errors.New(e.ErrMsg) 43 case ErrTypeUserError: 44 err = errutil.UserError{Err: e.ErrMsg} 45 case ErrTypeInternalError: 46 err = errutil.InternalError{Err: e.ErrMsg} 47 case ErrTypeCodedError: 48 err = logical.CodedError(int(e.ErrCode), e.ErrMsg) 49 case ErrTypeStatusBadRequest: 50 err = &logical.StatusBadRequest{Err: e.ErrMsg} 51 case ErrTypeUnsupportedOperation: 52 err = logical.ErrUnsupportedOperation 53 case ErrTypeUnsupportedPath: 54 err = logical.ErrUnsupportedPath 55 case ErrTypeInvalidRequest: 56 err = logical.ErrInvalidRequest 57 case ErrTypePermissionDenied: 58 err = logical.ErrPermissionDenied 59 case ErrTypeMultiAuthzPending: 60 err = logical.ErrMultiAuthzPending 61 case ErrTypeUnrecoverable: 62 err = logical.ErrUnrecoverable 63 } 64 65 return err 66 } 67 68 func ErrToProtoErr(e error) *ProtoError { 69 if e == nil { 70 return nil 71 } 72 pbErr := &ProtoError{ 73 ErrMsg: e.Error(), 74 ErrType: ErrTypeUnknown, 75 } 76 77 switch e.(type) { 78 case errutil.UserError: 79 pbErr.ErrType = ErrTypeUserError 80 case errutil.InternalError: 81 pbErr.ErrType = ErrTypeInternalError 82 case logical.HTTPCodedError: 83 pbErr.ErrType = ErrTypeCodedError 84 pbErr.ErrCode = int64(e.(logical.HTTPCodedError).Code()) 85 case *logical.StatusBadRequest: 86 pbErr.ErrType = ErrTypeStatusBadRequest 87 } 88 89 switch { 90 case e == logical.ErrUnsupportedOperation: 91 pbErr.ErrType = ErrTypeUnsupportedOperation 92 case e == logical.ErrUnsupportedPath: 93 pbErr.ErrType = ErrTypeUnsupportedPath 94 case e == logical.ErrInvalidRequest: 95 pbErr.ErrType = ErrTypeInvalidRequest 96 case e == logical.ErrPermissionDenied: 97 pbErr.ErrType = ErrTypePermissionDenied 98 case e == logical.ErrMultiAuthzPending: 99 pbErr.ErrType = ErrTypeMultiAuthzPending 100 case e == logical.ErrUnrecoverable: 101 pbErr.ErrType = ErrTypeUnrecoverable 102 } 103 104 return pbErr 105 } 106 107 func ErrToString(e error) string { 108 if e == nil { 109 return "" 110 } 111 112 return e.Error() 113 } 114 115 func LogicalStorageEntryToProtoStorageEntry(e *logical.StorageEntry) *StorageEntry { 116 if e == nil { 117 return nil 118 } 119 120 return &StorageEntry{ 121 Key: e.Key, 122 Value: e.Value, 123 SealWrap: e.SealWrap, 124 } 125 } 126 127 func ProtoStorageEntryToLogicalStorageEntry(e *StorageEntry) *logical.StorageEntry { 128 if e == nil { 129 return nil 130 } 131 132 return &logical.StorageEntry{ 133 Key: e.Key, 134 Value: e.Value, 135 SealWrap: e.SealWrap, 136 } 137 } 138 139 func ProtoLeaseOptionsToLogicalLeaseOptions(l *LeaseOptions) (logical.LeaseOptions, error) { 140 if l == nil { 141 return logical.LeaseOptions{}, nil 142 } 143 144 t, err := ptypes.Timestamp(l.IssueTime) 145 return logical.LeaseOptions{ 146 TTL: time.Duration(l.TTL), 147 Renewable: l.Renewable, 148 Increment: time.Duration(l.Increment), 149 IssueTime: t, 150 MaxTTL: time.Duration(l.MaxTTL), 151 }, err 152 } 153 154 func LogicalLeaseOptionsToProtoLeaseOptions(l logical.LeaseOptions) (*LeaseOptions, error) { 155 t, err := ptypes.TimestampProto(l.IssueTime) 156 if err != nil { 157 return nil, err 158 } 159 160 return &LeaseOptions{ 161 TTL: int64(l.TTL), 162 Renewable: l.Renewable, 163 Increment: int64(l.Increment), 164 IssueTime: t, 165 MaxTTL: int64(l.MaxTTL), 166 }, err 167 } 168 169 func ProtoSecretToLogicalSecret(s *Secret) (*logical.Secret, error) { 170 if s == nil { 171 return nil, nil 172 } 173 174 data := map[string]interface{}{} 175 err := json.Unmarshal([]byte(s.InternalData), &data) 176 if err != nil { 177 return nil, err 178 } 179 180 lease, err := ProtoLeaseOptionsToLogicalLeaseOptions(s.LeaseOptions) 181 if err != nil { 182 return nil, err 183 } 184 185 return &logical.Secret{ 186 LeaseOptions: lease, 187 InternalData: data, 188 LeaseID: s.LeaseID, 189 }, nil 190 } 191 192 func LogicalSecretToProtoSecret(s *logical.Secret) (*Secret, error) { 193 if s == nil { 194 return nil, nil 195 } 196 197 buf, err := json.Marshal(s.InternalData) 198 if err != nil { 199 return nil, err 200 } 201 202 lease, err := LogicalLeaseOptionsToProtoLeaseOptions(s.LeaseOptions) 203 if err != nil { 204 return nil, err 205 } 206 207 return &Secret{ 208 LeaseOptions: lease, 209 InternalData: string(buf[:]), 210 LeaseID: s.LeaseID, 211 }, err 212 } 213 214 func LogicalRequestToProtoRequest(r *logical.Request) (*Request, error) { 215 if r == nil { 216 return nil, nil 217 } 218 219 buf, err := json.Marshal(r.Data) 220 if err != nil { 221 return nil, err 222 } 223 224 secret, err := LogicalSecretToProtoSecret(r.Secret) 225 if err != nil { 226 return nil, err 227 } 228 229 auth, err := LogicalAuthToProtoAuth(r.Auth) 230 if err != nil { 231 return nil, err 232 } 233 234 headers := map[string]*Header{} 235 for k, v := range r.Headers { 236 headers[k] = &Header{Header: v} 237 } 238 239 return &Request{ 240 ID: r.ID, 241 ReplicationCluster: r.ReplicationCluster, 242 Operation: string(r.Operation), 243 Path: r.Path, 244 Data: string(buf[:]), 245 Secret: secret, 246 Auth: auth, 247 Headers: headers, 248 ClientToken: r.ClientToken, 249 ClientTokenAccessor: r.ClientTokenAccessor, 250 DisplayName: r.DisplayName, 251 MountPoint: r.MountPoint, 252 MountType: r.MountType, 253 MountAccessor: r.MountAccessor, 254 WrapInfo: LogicalRequestWrapInfoToProtoRequestWrapInfo(r.WrapInfo), 255 ClientTokenRemainingUses: int64(r.ClientTokenRemainingUses), 256 Connection: LogicalConnectionToProtoConnection(r.Connection), 257 EntityID: r.EntityID, 258 PolicyOverride: r.PolicyOverride, 259 Unauthenticated: r.Unauthenticated, 260 }, nil 261 } 262 263 func ProtoRequestToLogicalRequest(r *Request) (*logical.Request, error) { 264 if r == nil { 265 return nil, nil 266 } 267 268 data := map[string]interface{}{} 269 err := json.Unmarshal([]byte(r.Data), &data) 270 if err != nil { 271 return nil, err 272 } 273 274 secret, err := ProtoSecretToLogicalSecret(r.Secret) 275 if err != nil { 276 return nil, err 277 } 278 279 auth, err := ProtoAuthToLogicalAuth(r.Auth) 280 if err != nil { 281 return nil, err 282 } 283 284 var headers map[string][]string 285 if len(r.Headers) > 0 { 286 headers = make(map[string][]string, len(r.Headers)) 287 for k, v := range r.Headers { 288 headers[k] = v.Header 289 } 290 } 291 292 connection, err := ProtoConnectionToLogicalConnection(r.Connection) 293 if err != nil { 294 return nil, err 295 } 296 297 return &logical.Request{ 298 ID: r.ID, 299 ReplicationCluster: r.ReplicationCluster, 300 Operation: logical.Operation(r.Operation), 301 Path: r.Path, 302 Data: data, 303 Secret: secret, 304 Auth: auth, 305 Headers: headers, 306 ClientToken: r.ClientToken, 307 ClientTokenAccessor: r.ClientTokenAccessor, 308 DisplayName: r.DisplayName, 309 MountPoint: r.MountPoint, 310 MountType: r.MountType, 311 MountAccessor: r.MountAccessor, 312 WrapInfo: ProtoRequestWrapInfoToLogicalRequestWrapInfo(r.WrapInfo), 313 ClientTokenRemainingUses: int(r.ClientTokenRemainingUses), 314 Connection: connection, 315 EntityID: r.EntityID, 316 PolicyOverride: r.PolicyOverride, 317 Unauthenticated: r.Unauthenticated, 318 }, nil 319 } 320 321 func LogicalConnectionToProtoConnection(c *logical.Connection) *Connection { 322 if c == nil { 323 return nil 324 } 325 326 return &Connection{ 327 RemoteAddr: c.RemoteAddr, 328 ConnectionState: TLSConnectionStateToProtoConnectionState(c.ConnState), 329 } 330 } 331 332 func ProtoConnectionToLogicalConnection(c *Connection) (*logical.Connection, error) { 333 if c == nil { 334 return nil, nil 335 } 336 337 cs, err := ProtoConnectionStateToTLSConnectionState(c.ConnectionState) 338 if err != nil { 339 return nil, err 340 } 341 342 return &logical.Connection{ 343 RemoteAddr: c.RemoteAddr, 344 ConnState: cs, 345 }, nil 346 } 347 348 func LogicalRequestWrapInfoToProtoRequestWrapInfo(i *logical.RequestWrapInfo) *RequestWrapInfo { 349 if i == nil { 350 return nil 351 } 352 353 return &RequestWrapInfo{ 354 TTL: int64(i.TTL), 355 Format: i.Format, 356 SealWrap: i.SealWrap, 357 } 358 } 359 360 func ProtoRequestWrapInfoToLogicalRequestWrapInfo(i *RequestWrapInfo) *logical.RequestWrapInfo { 361 if i == nil { 362 return nil 363 } 364 365 return &logical.RequestWrapInfo{ 366 TTL: time.Duration(i.TTL), 367 Format: i.Format, 368 SealWrap: i.SealWrap, 369 } 370 } 371 372 func ProtoResponseToLogicalResponse(r *Response) (*logical.Response, error) { 373 if r == nil { 374 return nil, nil 375 } 376 377 secret, err := ProtoSecretToLogicalSecret(r.Secret) 378 if err != nil { 379 return nil, err 380 } 381 382 auth, err := ProtoAuthToLogicalAuth(r.Auth) 383 if err != nil { 384 return nil, err 385 } 386 387 data := map[string]interface{}{} 388 err = json.Unmarshal([]byte(r.Data), &data) 389 if err != nil { 390 return nil, err 391 } 392 393 wrapInfo, err := ProtoResponseWrapInfoToLogicalResponseWrapInfo(r.WrapInfo) 394 if err != nil { 395 return nil, err 396 } 397 398 var headers map[string][]string 399 if len(r.Headers) > 0 { 400 headers = make(map[string][]string, len(r.Headers)) 401 for k, v := range r.Headers { 402 headers[k] = v.Header 403 } 404 } 405 406 return &logical.Response{ 407 Secret: secret, 408 Auth: auth, 409 Data: data, 410 Redirect: r.Redirect, 411 Warnings: r.Warnings, 412 WrapInfo: wrapInfo, 413 Headers: headers, 414 MountType: r.MountType, 415 }, nil 416 } 417 418 func ProtoResponseWrapInfoToLogicalResponseWrapInfo(i *ResponseWrapInfo) (*wrapping.ResponseWrapInfo, error) { 419 if i == nil { 420 return nil, nil 421 } 422 423 t, err := ptypes.Timestamp(i.CreationTime) 424 if err != nil { 425 return nil, err 426 } 427 428 return &wrapping.ResponseWrapInfo{ 429 TTL: time.Duration(i.TTL), 430 Token: i.Token, 431 Accessor: i.Accessor, 432 CreationTime: t, 433 WrappedAccessor: i.WrappedAccessor, 434 WrappedEntityID: i.WrappedEntityID, 435 Format: i.Format, 436 CreationPath: i.CreationPath, 437 SealWrap: i.SealWrap, 438 }, nil 439 } 440 441 func LogicalResponseWrapInfoToProtoResponseWrapInfo(i *wrapping.ResponseWrapInfo) (*ResponseWrapInfo, error) { 442 if i == nil { 443 return nil, nil 444 } 445 446 t, err := ptypes.TimestampProto(i.CreationTime) 447 if err != nil { 448 return nil, err 449 } 450 451 return &ResponseWrapInfo{ 452 TTL: int64(i.TTL), 453 Token: i.Token, 454 Accessor: i.Accessor, 455 CreationTime: t, 456 WrappedAccessor: i.WrappedAccessor, 457 WrappedEntityID: i.WrappedEntityID, 458 Format: i.Format, 459 CreationPath: i.CreationPath, 460 SealWrap: i.SealWrap, 461 }, nil 462 } 463 464 func LogicalResponseToProtoResponse(r *logical.Response) (*Response, error) { 465 if r == nil { 466 return nil, nil 467 } 468 469 secret, err := LogicalSecretToProtoSecret(r.Secret) 470 if err != nil { 471 return nil, err 472 } 473 474 auth, err := LogicalAuthToProtoAuth(r.Auth) 475 if err != nil { 476 return nil, err 477 } 478 479 buf, err := json.Marshal(r.Data) 480 if err != nil { 481 return nil, err 482 } 483 484 wrapInfo, err := LogicalResponseWrapInfoToProtoResponseWrapInfo(r.WrapInfo) 485 if err != nil { 486 return nil, err 487 } 488 489 headers := map[string]*Header{} 490 for k, v := range r.Headers { 491 headers[k] = &Header{Header: v} 492 } 493 494 return &Response{ 495 Secret: secret, 496 Auth: auth, 497 Data: string(buf[:]), 498 Redirect: r.Redirect, 499 Warnings: r.Warnings, 500 WrapInfo: wrapInfo, 501 Headers: headers, 502 MountType: r.MountType, 503 }, nil 504 } 505 506 func LogicalAuthToProtoAuth(a *logical.Auth) (*Auth, error) { 507 if a == nil { 508 return nil, nil 509 } 510 511 buf, err := json.Marshal(a.InternalData) 512 if err != nil { 513 return nil, err 514 } 515 516 lo, err := LogicalLeaseOptionsToProtoLeaseOptions(a.LeaseOptions) 517 if err != nil { 518 return nil, err 519 } 520 521 boundCIDRs := make([]string, len(a.BoundCIDRs)) 522 for i, cidr := range a.BoundCIDRs { 523 boundCIDRs[i] = cidr.String() 524 } 525 526 return &Auth{ 527 LeaseOptions: lo, 528 TokenType: uint32(a.TokenType), 529 InternalData: string(buf[:]), 530 DisplayName: a.DisplayName, 531 Policies: a.Policies, 532 TokenPolicies: a.TokenPolicies, 533 IdentityPolicies: a.IdentityPolicies, 534 NoDefaultPolicy: a.NoDefaultPolicy, 535 Metadata: a.Metadata, 536 ClientToken: a.ClientToken, 537 Accessor: a.Accessor, 538 Period: int64(a.Period), 539 NumUses: int64(a.NumUses), 540 EntityID: a.EntityID, 541 Alias: a.Alias, 542 GroupAliases: a.GroupAliases, 543 BoundCIDRs: boundCIDRs, 544 ExplicitMaxTTL: int64(a.ExplicitMaxTTL), 545 }, nil 546 } 547 548 func ProtoAuthToLogicalAuth(a *Auth) (*logical.Auth, error) { 549 if a == nil { 550 return nil, nil 551 } 552 553 data := map[string]interface{}{} 554 err := json.Unmarshal([]byte(a.InternalData), &data) 555 if err != nil { 556 return nil, err 557 } 558 559 lo, err := ProtoLeaseOptionsToLogicalLeaseOptions(a.LeaseOptions) 560 if err != nil { 561 return nil, err 562 } 563 564 boundCIDRs, err := parseutil.ParseAddrs(a.BoundCIDRs) 565 if err != nil { 566 return nil, err 567 } 568 if len(boundCIDRs) == 0 { 569 // On inbound auths, if auth.BoundCIDRs is empty, it will be nil. 570 // Let's match that behavior outbound. 571 boundCIDRs = nil 572 } 573 574 return &logical.Auth{ 575 LeaseOptions: lo, 576 TokenType: logical.TokenType(a.TokenType), 577 InternalData: data, 578 DisplayName: a.DisplayName, 579 Policies: a.Policies, 580 TokenPolicies: a.TokenPolicies, 581 IdentityPolicies: a.IdentityPolicies, 582 NoDefaultPolicy: a.NoDefaultPolicy, 583 Metadata: a.Metadata, 584 ClientToken: a.ClientToken, 585 Accessor: a.Accessor, 586 Period: time.Duration(a.Period), 587 NumUses: int(a.NumUses), 588 EntityID: a.EntityID, 589 Alias: a.Alias, 590 GroupAliases: a.GroupAliases, 591 BoundCIDRs: boundCIDRs, 592 ExplicitMaxTTL: time.Duration(a.ExplicitMaxTTL), 593 }, nil 594 } 595 596 func LogicalTokenEntryToProtoTokenEntry(t *logical.TokenEntry) *TokenEntry { 597 if t == nil { 598 return nil 599 } 600 601 boundCIDRs := make([]string, len(t.BoundCIDRs)) 602 for i, cidr := range t.BoundCIDRs { 603 boundCIDRs[i] = cidr.String() 604 } 605 606 return &TokenEntry{ 607 ID: t.ID, 608 Accessor: t.Accessor, 609 Parent: t.Parent, 610 Policies: t.Policies, 611 InlinePolicy: t.InlinePolicy, 612 Path: t.Path, 613 Meta: t.Meta, 614 InternalMeta: t.InternalMeta, 615 DisplayName: t.DisplayName, 616 NumUses: int64(t.NumUses), 617 CreationTime: t.CreationTime, 618 TTL: int64(t.TTL), 619 ExplicitMaxTTL: int64(t.ExplicitMaxTTL), 620 Role: t.Role, 621 Period: int64(t.Period), 622 EntityID: t.EntityID, 623 NoIdentityPolicies: t.NoIdentityPolicies, 624 BoundCIDRs: boundCIDRs, 625 NamespaceID: t.NamespaceID, 626 CubbyholeID: t.CubbyholeID, 627 Type: uint32(t.Type), 628 ExternalID: t.ExternalID, 629 } 630 } 631 632 func ProtoTokenEntryToLogicalTokenEntry(t *TokenEntry) (*logical.TokenEntry, error) { 633 if t == nil { 634 return nil, nil 635 } 636 637 boundCIDRs, err := parseutil.ParseAddrs(t.BoundCIDRs) 638 if err != nil { 639 return nil, err 640 } 641 if len(boundCIDRs) == 0 { 642 // On inbound auths, if auth.BoundCIDRs is empty, it will be nil. 643 // Let's match that behavior outbound. 644 boundCIDRs = nil 645 } 646 647 return &logical.TokenEntry{ 648 ID: t.ID, 649 Accessor: t.Accessor, 650 Parent: t.Parent, 651 Policies: t.Policies, 652 InlinePolicy: t.InlinePolicy, 653 Path: t.Path, 654 Meta: t.Meta, 655 InternalMeta: t.InternalMeta, 656 DisplayName: t.DisplayName, 657 NumUses: int(t.NumUses), 658 CreationTime: t.CreationTime, 659 TTL: time.Duration(t.TTL), 660 ExplicitMaxTTL: time.Duration(t.ExplicitMaxTTL), 661 Role: t.Role, 662 Period: time.Duration(t.Period), 663 EntityID: t.EntityID, 664 NoIdentityPolicies: t.NoIdentityPolicies, 665 BoundCIDRs: boundCIDRs, 666 NamespaceID: t.NamespaceID, 667 CubbyholeID: t.CubbyholeID, 668 Type: logical.TokenType(t.Type), 669 ExternalID: t.ExternalID, 670 }, nil 671 } 672 673 func TLSConnectionStateToProtoConnectionState(connState *tls.ConnectionState) *ConnectionState { 674 if connState == nil { 675 return nil 676 } 677 678 var verifiedChains []*CertificateChain 679 680 if lvc := len(connState.VerifiedChains); lvc > 0 { 681 verifiedChains = make([]*CertificateChain, lvc) 682 for i, vc := range connState.VerifiedChains { 683 verifiedChains[i] = CertificateChainToProtoCertificateChain(vc) 684 } 685 } 686 687 return &ConnectionState{ 688 Version: uint32(connState.Version), 689 HandshakeComplete: connState.HandshakeComplete, 690 DidResume: connState.DidResume, 691 CipherSuite: uint32(connState.CipherSuite), 692 NegotiatedProtocol: connState.NegotiatedProtocol, 693 NegotiatedProtocolIsMutual: connState.NegotiatedProtocolIsMutual, 694 ServerName: connState.ServerName, 695 PeerCertificates: CertificateChainToProtoCertificateChain(connState.PeerCertificates), 696 VerifiedChains: verifiedChains, 697 SignedCertificateTimestamps: connState.SignedCertificateTimestamps, 698 OcspResponse: connState.OCSPResponse, 699 TlsUnique: connState.TLSUnique, 700 } 701 } 702 703 func ProtoConnectionStateToTLSConnectionState(cs *ConnectionState) (*tls.ConnectionState, error) { 704 if cs == nil { 705 return nil, nil 706 } 707 708 var ( 709 err error 710 peerCertificates []*x509.Certificate 711 verifiedChains [][]*x509.Certificate 712 ) 713 714 if peerCertificates, err = ProtoCertificateChainToCertificateChain(cs.PeerCertificates); err != nil { 715 return nil, err 716 } 717 718 if lvc := len(cs.VerifiedChains); lvc > 0 { 719 verifiedChains = make([][]*x509.Certificate, lvc) 720 for i, vc := range cs.VerifiedChains { 721 if verifiedChains[i], err = ProtoCertificateChainToCertificateChain(vc); err != nil { 722 return nil, err 723 } 724 } 725 } 726 727 connState := &tls.ConnectionState{ 728 Version: uint16(cs.Version), 729 HandshakeComplete: cs.HandshakeComplete, 730 DidResume: cs.DidResume, 731 CipherSuite: uint16(cs.CipherSuite), 732 NegotiatedProtocol: cs.NegotiatedProtocol, 733 NegotiatedProtocolIsMutual: cs.NegotiatedProtocolIsMutual, 734 ServerName: cs.ServerName, 735 PeerCertificates: peerCertificates, 736 VerifiedChains: verifiedChains, 737 SignedCertificateTimestamps: cs.SignedCertificateTimestamps, 738 OCSPResponse: cs.OcspResponse, 739 TLSUnique: cs.TlsUnique, 740 } 741 742 return connState, nil 743 } 744 745 func CertificateChainToProtoCertificateChain(chain []*x509.Certificate) *CertificateChain { 746 if len(chain) == 0 { 747 return nil 748 } 749 750 cc := &CertificateChain{Certificates: make([]*Certificate, len(chain))} 751 752 for i, c := range chain { 753 cc.Certificates[i] = X509CertificateToProtoCertificate(c) 754 } 755 756 return cc 757 } 758 759 func ProtoCertificateChainToCertificateChain(cc *CertificateChain) ([]*x509.Certificate, error) { 760 if cc == nil || len(cc.Certificates) == 0 { 761 return nil, nil 762 } 763 764 certs := make([]*x509.Certificate, len(cc.Certificates)) 765 766 for i, c := range cc.Certificates { 767 var err error 768 if certs[i], err = ProtoCertificateToX509Certificate(c); err != nil { 769 return nil, err 770 } 771 } 772 773 return certs, nil 774 } 775 776 func X509CertificateToProtoCertificate(cert *x509.Certificate) *Certificate { 777 if cert == nil { 778 return nil 779 } 780 781 return &Certificate{Asn1Data: cert.Raw} 782 } 783 784 func ProtoCertificateToX509Certificate(c *Certificate) (*x509.Certificate, error) { 785 if c == nil { 786 return nil, nil 787 } 788 789 return x509.ParseCertificate(c.Asn1Data) 790 }