go110.go 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. // +build go1.10
  2. /*
  3. *
  4. * Copyright 2020 gRPC authors.
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the "License");
  7. * you may not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. *
  18. */
  19. // Package credentials defines APIs for parsing SPIFFE ID.
  20. //
  21. // All APIs in this package are experimental.
  22. package credentials
  23. import (
  24. "crypto/tls"
  25. "net/url"
  26. "google.golang.org/grpc/grpclog"
  27. )
  28. // SPIFFEIDFromState parses the SPIFFE ID from State. If the SPIFFE ID format
  29. // is invalid, return nil with warning.
  30. func SPIFFEIDFromState(state tls.ConnectionState) *url.URL {
  31. if len(state.PeerCertificates) == 0 || len(state.PeerCertificates[0].URIs) == 0 {
  32. return nil
  33. }
  34. var spiffeID *url.URL
  35. for _, uri := range state.PeerCertificates[0].URIs {
  36. if uri == nil || uri.Scheme != "spiffe" || uri.Opaque != "" || (uri.User != nil && uri.User.Username() != "") {
  37. continue
  38. }
  39. // From this point, we assume the uri is intended for a SPIFFE ID.
  40. if len(uri.String()) > 2048 {
  41. grpclog.Warning("invalid SPIFFE ID: total ID length larger than 2048 bytes")
  42. return nil
  43. }
  44. if len(uri.Host) == 0 || len(uri.RawPath) == 0 || len(uri.Path) == 0 {
  45. grpclog.Warning("invalid SPIFFE ID: domain or workload ID is empty")
  46. return nil
  47. }
  48. if len(uri.Host) > 255 {
  49. grpclog.Warning("invalid SPIFFE ID: domain length larger than 255 characters")
  50. return nil
  51. }
  52. // A valid SPIFFE certificate can only have exactly one URI SAN field.
  53. if len(state.PeerCertificates[0].URIs) > 1 {
  54. grpclog.Warning("invalid SPIFFE ID: multiple URI SANs")
  55. return nil
  56. }
  57. spiffeID = uri
  58. }
  59. return spiffeID
  60. }