PageRenderTime 73ms CodeModel.GetById 29ms RepoModel.GetById 1ms app.codeStats 0ms

/framework/src/play-ws/src/main/scala/play/api/libs/ws/ssl/CompositeX509KeyManager.scala

https://gitlab.com/KiaraGrouwstra/playframework
Scala | 165 lines | 124 code | 22 blank | 19 comment | 20 complexity | db1129dd39d0475a6e42f1e383203d7d MD5 | raw file
  1. /*
  2. *
  3. * * Copyright (C) 2009-2015 Typesafe Inc. <http://www.typesafe.com>
  4. *
  5. */
  6. package play.api.libs.ws.ssl
  7. import javax.net.ssl.{ SSLEngine, X509ExtendedKeyManager, X509KeyManager }
  8. import java.security.{ Principal, PrivateKey }
  9. import java.security.cert.{ CertificateException, X509Certificate }
  10. import java.net.Socket
  11. import scala.collection.mutable.ArrayBuffer
  12. /**
  13. * A keymanager that wraps other X509 key managers.
  14. */
  15. class CompositeX509KeyManager(keyManagers: Seq[X509KeyManager]) extends X509ExtendedKeyManager {
  16. // Must specify X509ExtendedKeyManager: otherwise you get
  17. // "X509KeyManager passed to SSLContext.init(): need an X509ExtendedKeyManager for SSLEngine use"
  18. private val logger = org.slf4j.LoggerFactory.getLogger(getClass)
  19. logger.debug(s"CompositeX509KeyManager start: keyManagers = $keyManagers")
  20. // You would think that from the method signature that you could use multiple key managers and trust managers
  21. // by passing them as an array in the init method. However, the fine print explicitly says:
  22. // "Only the first instance of a particular key and/or trust manager implementation type in the array is used.
  23. // (For example, only the first javax.net.ssl.X509KeyManager in the array will be used.)"
  24. //
  25. // This doesn't mean you can't have multiple key managers, but that you can't have multiple key managers of
  26. // the same class, i.e. you can't have two X509KeyManagers in the array.
  27. def getClientAliases(keyType: String, issuers: Array[Principal]): Array[String] = {
  28. logger.debug(s"getClientAliases: keyType = $keyType, issuers = ${issuers.toSeq}")
  29. val clientAliases = new ArrayBuffer[String]
  30. withKeyManagers { keyManager =>
  31. val aliases = keyManager.getClientAliases(keyType, issuers)
  32. if (aliases != null) {
  33. clientAliases.appendAll(aliases)
  34. }
  35. }
  36. logger.debug(s"getCertificateChain: clientAliases = $clientAliases")
  37. nullIfEmpty(clientAliases.toArray)
  38. }
  39. def chooseClientAlias(keyType: Array[String], issuers: Array[Principal], socket: Socket): String = {
  40. logger.debug(s"chooseClientAlias: keyType = ${keyType.toSeq}, issuers = ${issuers.toSeq}, socket = $socket")
  41. withKeyManagers { keyManager =>
  42. val clientAlias = keyManager.chooseClientAlias(keyType, issuers, socket)
  43. if (clientAlias != null) {
  44. logger.debug(s"chooseClientAlias: using clientAlias $clientAlias with keyManager $keyManager")
  45. return clientAlias
  46. }
  47. }
  48. null
  49. }
  50. override def chooseEngineClientAlias(keyType: Array[String], issuers: Array[Principal], engine: SSLEngine): String = {
  51. logger.debug(s"chooseEngineClientAlias: keyType = ${keyType.toSeq}, issuers = ${issuers.toSeq}, engine = $engine")
  52. withKeyManagers { keyManager: X509KeyManager =>
  53. keyManager match {
  54. case extendedKeyManager: X509ExtendedKeyManager =>
  55. val clientAlias = extendedKeyManager.chooseEngineClientAlias(keyType, issuers, engine)
  56. if (clientAlias != null) {
  57. logger.debug(s"chooseEngineClientAlias: using clientAlias $clientAlias with keyManager $extendedKeyManager")
  58. return clientAlias
  59. }
  60. case _ =>
  61. // do nothing
  62. }
  63. }
  64. null
  65. }
  66. override def chooseEngineServerAlias(keyType: String, issuers: Array[Principal], engine: SSLEngine): String = {
  67. logger.debug(s"chooseEngineServerAlias: keyType = ${keyType.toSeq}, issuers = ${issuers.toSeq}, engine = $engine")
  68. withKeyManagers { keyManager: X509KeyManager =>
  69. keyManager match {
  70. case extendedKeyManager: X509ExtendedKeyManager =>
  71. val clientAlias = extendedKeyManager.chooseEngineServerAlias(keyType, issuers, engine)
  72. if (clientAlias != null) {
  73. logger.debug(s"chooseEngineServerAlias: using clientAlias $clientAlias with keyManager $extendedKeyManager")
  74. return clientAlias
  75. }
  76. case _ =>
  77. // do nothing
  78. }
  79. }
  80. null
  81. }
  82. def getServerAliases(keyType: String, issuers: Array[Principal]): Array[String] = {
  83. logger.debug(s"getServerAliases: keyType = $keyType, issuers = ${issuers.toSeq}")
  84. val serverAliases = new ArrayBuffer[String]
  85. withKeyManagers { keyManager =>
  86. val aliases = keyManager.getServerAliases(keyType, issuers)
  87. if (aliases != null) {
  88. serverAliases.appendAll(aliases)
  89. }
  90. }
  91. logger.debug(s"getServerAliases: serverAliases = $serverAliases")
  92. nullIfEmpty(serverAliases.toArray)
  93. }
  94. def chooseServerAlias(keyType: String, issuers: Array[Principal], socket: Socket): String = {
  95. logger.debug(s"chooseServerAlias: keyType = $keyType, issuers = ${issuers.toSeq}, socket = $socket")
  96. withKeyManagers { keyManager =>
  97. val serverAlias = keyManager.chooseServerAlias(keyType, issuers, socket)
  98. if (serverAlias != null) {
  99. logger.debug(s"chooseServerAlias: using serverAlias $serverAlias with keyManager $keyManager")
  100. return serverAlias
  101. }
  102. }
  103. null
  104. }
  105. def getCertificateChain(alias: String): Array[X509Certificate] = {
  106. logger.debug(s"getCertificateChain: alias = $alias")
  107. withKeyManagers { keyManager =>
  108. val chain = keyManager.getCertificateChain(alias)
  109. if (chain != null && chain.length > 0) {
  110. logger.debug(s"getCertificateChain: chain ${debugChain(chain)} with keyManager $keyManager")
  111. return chain
  112. }
  113. }
  114. null
  115. }
  116. def getPrivateKey(alias: String): PrivateKey = {
  117. logger.debug(s"getPrivateKey: alias = $alias")
  118. withKeyManagers { keyManager =>
  119. val privateKey = keyManager.getPrivateKey(alias)
  120. if (privateKey != null) {
  121. logger.debug(s"getPrivateKey: privateKey $privateKey with keyManager $keyManager")
  122. return privateKey
  123. }
  124. }
  125. null
  126. }
  127. private def withKeyManagers[T](block: (X509KeyManager => T)): Seq[CertificateException] = {
  128. val exceptionList = ArrayBuffer[CertificateException]()
  129. keyManagers.foreach { keyManager =>
  130. try {
  131. block(keyManager)
  132. } catch {
  133. case certEx: CertificateException =>
  134. exceptionList.append(certEx)
  135. }
  136. }
  137. exceptionList
  138. }
  139. private def nullIfEmpty[T](array: Array[T]) = if (array.size == 0) null else array
  140. override def toString = {
  141. s"CompositeX509KeyManager(keyManagers = [$keyManagers])"
  142. }
  143. }