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  }