1 /** 2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 * SPDX-License-Identifier: Apache-2.0. 4 */ 5 package software.amazon.awssdk.crt.auth.credentials; 6 7 import java.lang.IllegalArgumentException; 8 import java.nio.charset.Charset; 9 import software.amazon.awssdk.crt.http.HttpProxyOptions; 10 import software.amazon.awssdk.crt.io.ClientBootstrap; 11 import software.amazon.awssdk.crt.io.TlsContext; 12 13 /** 14 * A class that wraps a credentials provider that sources session credentials from IoT's x509 credentials 15 * service. 16 */ 17 public class X509CredentialsProvider extends CredentialsProvider { 18 19 private final static Charset UTF8 = java.nio.charset.StandardCharsets.UTF_8; 20 21 /** 22 * A builder class for the 509 provider and its options 23 */ 24 static public class X509CredentialsProviderBuilder { 25 26 private String thingName; 27 private String roleAlias; 28 private String endpoint; 29 30 private TlsContext tlsContext; 31 private ClientBootstrap clientBootstrap; 32 private HttpProxyOptions proxyOptions; 33 34 /** 35 * Default constructor 36 */ X509CredentialsProviderBuilder()37 public X509CredentialsProviderBuilder() {} 38 39 /** 40 * Sets the client bootstrap (host resolver and event loop group) to use when making the connections 41 * required by this provider. 42 * @param clientBootstrap client bootstrap to use 43 * @return The current builder 44 */ withClientBootstrap(ClientBootstrap clientBootstrap)45 public X509CredentialsProviderBuilder withClientBootstrap(ClientBootstrap clientBootstrap) { 46 this.clientBootstrap = clientBootstrap; 47 48 return this; 49 } 50 getClientBootstrap()51 ClientBootstrap getClientBootstrap() { return clientBootstrap; } 52 53 /** 54 * Sets the tls context initialized with a x509 certificate and private key suitable for 55 * queries against the account's iot credential provider endpoint 56 * @param tlsContext the tls context to use when establishing the http connection to iot 57 * @return The current builder 58 */ withTlsContext(TlsContext tlsContext)59 public X509CredentialsProviderBuilder withTlsContext(TlsContext tlsContext) { 60 this.tlsContext = tlsContext; 61 62 return this; 63 } 64 getTlsContext()65 TlsContext getTlsContext() { return tlsContext; } 66 67 /** 68 * Sets the iot thing name to fetch credentials by. 69 * @param thingName name of the thing to use 70 * @return The current builder 71 */ withThingName(String thingName)72 public X509CredentialsProviderBuilder withThingName(String thingName) { 73 this.thingName = thingName; 74 75 return this; 76 } 77 getThingName()78 String getThingName() { return thingName; } 79 80 /** 81 * Sets the role alias to fetch credentials through 82 * @param roleAlias name of the role alias to use 83 * @return The current builder 84 */ withRoleAlias(String roleAlias)85 public X509CredentialsProviderBuilder withRoleAlias(String roleAlias) { 86 this.roleAlias = roleAlias; 87 88 return this; 89 } 90 getRoleAlias()91 String getRoleAlias() { return roleAlias; } 92 93 /** 94 * Sets the endpoint to fetch credentials from. This is a per-account value that can be determined 95 * via the cli: 'aws iot describe-endpoint --endpoint-type iot:CredentialProvider' 96 * @param endpoint credentials provider endpoint 97 * @return The current builder 98 */ withEndpoint(String endpoint)99 public X509CredentialsProviderBuilder withEndpoint(String endpoint) { 100 this.endpoint = endpoint; 101 102 return this; 103 } 104 getEndpoint()105 String getEndpoint() { return endpoint; } 106 107 /** 108 * Sets the proxy configuration to use when making the http request that fetches session 109 * credentials from the IoT x509 credentials provider service 110 * @param proxyOptions proxy configuration for the credentials fetching http request 111 * @return The current builder 112 */ withProxyOptions(HttpProxyOptions proxyOptions)113 public X509CredentialsProviderBuilder withProxyOptions(HttpProxyOptions proxyOptions) { 114 this.proxyOptions = proxyOptions; 115 116 return this; 117 } 118 getProxyOptions()119 HttpProxyOptions getProxyOptions() { return proxyOptions; } 120 121 122 /** 123 * Creates a new X509 credentials provider, based on this builder's configuration 124 * @return a new X509 credentials provider 125 */ build()126 public X509CredentialsProvider build() { 127 return new X509CredentialsProvider(this); 128 } 129 } 130 X509CredentialsProvider(X509CredentialsProviderBuilder builder)131 private X509CredentialsProvider(X509CredentialsProviderBuilder builder) { 132 super(); 133 134 String thingName = builder.getThingName(); 135 String roleAlias = builder.getRoleAlias(); 136 String endpoint = builder.getEndpoint(); 137 if (thingName == null || roleAlias == null || endpoint == null) { 138 throw new IllegalArgumentException("X509CredentialsProvider - thingName, roleAlias, and endpoint must be non null"); 139 } 140 141 ClientBootstrap clientBootstrap = builder.getClientBootstrap(); 142 if (clientBootstrap == null) { 143 clientBootstrap = ClientBootstrap.getOrCreateStaticDefault(); 144 } 145 146 TlsContext tlsContext = builder.getTlsContext(); 147 if (clientBootstrap == null || tlsContext == null) { 148 throw new IllegalArgumentException("X509CredentialsProvider - clientBootstrap and tlsContext must be non null"); 149 } 150 151 int proxyConnectionType = 0; 152 long proxyTlsContextHandle = 0; 153 String proxyHost = null; 154 int proxyPort = 0; 155 int proxyAuthorizationType = 0; 156 String proxyAuthorizationUsername = null; 157 String proxyAuthorizationPassword = null; 158 HttpProxyOptions proxyOptions = builder.getProxyOptions(); 159 if (proxyOptions != null) { 160 proxyConnectionType = proxyOptions.getConnectionType().getValue(); 161 TlsContext proxyTlsContext = proxyOptions.getTlsContext(); 162 if (proxyTlsContext != null) { 163 proxyTlsContextHandle = proxyTlsContext.getNativeHandle(); 164 } 165 166 proxyHost = proxyOptions.getHost(); 167 proxyPort = proxyOptions.getPort(); 168 proxyAuthorizationType = proxyOptions.getAuthorizationType().getValue(); 169 proxyAuthorizationUsername = proxyOptions.getAuthorizationUsername(); 170 proxyAuthorizationPassword = proxyOptions.getAuthorizationPassword(); 171 } 172 173 long nativeHandle = x509CredentialsProviderNew( 174 this, 175 clientBootstrap.getNativeHandle(), 176 tlsContext.getNativeHandle(), 177 thingName.getBytes(UTF8), 178 roleAlias.getBytes(UTF8), 179 endpoint.getBytes(UTF8), 180 proxyConnectionType, 181 proxyHost != null ? proxyHost.getBytes(UTF8) : null, 182 proxyPort, 183 proxyTlsContextHandle, 184 proxyAuthorizationType, 185 proxyAuthorizationUsername != null ? proxyAuthorizationUsername.getBytes(UTF8) : null, 186 proxyAuthorizationPassword != null ? proxyAuthorizationPassword.getBytes(UTF8) : null); 187 188 acquireNativeHandle(nativeHandle); 189 addReferenceTo(clientBootstrap); 190 addReferenceTo(tlsContext); 191 } 192 193 /******************************************************************************* 194 * Native methods 195 ******************************************************************************/ 196 x509CredentialsProviderNew(X509CredentialsProvider thisObj, long bootstrapHandle, long tlsContextHandle, byte[] thingName, byte[] roleAlias, byte[] endpoint, int proxyConnectionType, byte[] proxyHost, int proxyPort, long proxyTlsContext, int proxyAuthorizationType, byte[] proxyAuthorizationUsername, byte[] proxyAuthorizationPassword)197 private static native long x509CredentialsProviderNew(X509CredentialsProvider thisObj, 198 long bootstrapHandle, 199 long tlsContextHandle, 200 byte[] thingName, 201 byte[] roleAlias, 202 byte[] endpoint, 203 int proxyConnectionType, 204 byte[] proxyHost, 205 int proxyPort, 206 long proxyTlsContext, 207 int proxyAuthorizationType, 208 byte[] proxyAuthorizationUsername, 209 byte[] proxyAuthorizationPassword); 210 } 211