001/* 002 * Copyright 2023 Emmanuel Bourg 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package net.jsign.jca; 018 019import java.io.IOException; 020 021/** 022 * AWS credentials 023 * 024 * @since 5.0 025 */ 026public class AmazonCredentials { 027 028 private final String accessKey; 029 private final String secretKey; 030 private final String sessionToken; 031 032 public AmazonCredentials(String accessKey, String secretKey, String sessionToken) { 033 this.accessKey = accessKey; 034 this.secretKey = secretKey; 035 this.sessionToken = sessionToken; 036 } 037 038 public String getAccessKey() { 039 return accessKey; 040 } 041 042 public String getSecretKey() { 043 return secretKey; 044 } 045 046 public String getSessionToken() { 047 return sessionToken; 048 } 049 050 /** 051 * Parses the concatenated AWS credentials 052 * 053 * @param credentials <tt>accessKey|secretKey|sessionToken</tt> (the session token is optional) 054 */ 055 public static AmazonCredentials parse(String credentials) throws IllegalArgumentException { 056 // parse the credentials 057 String[] elements = credentials.split("\\|", 3); 058 if (elements.length < 2) { 059 throw new IllegalArgumentException("Invalid AWS credentials: " + credentials); 060 } 061 String accessKey = elements[0]; 062 String secretKey = elements[1]; 063 String sessionToken = elements.length > 2 ? elements[2] : null; 064 065 return new AmazonCredentials(accessKey, secretKey, sessionToken); 066 } 067 068 /** 069 * Returns the default AWS credentials, fetched from the following sources in order: 070 * <ul> 071 * <li>The environment variables <tt>AWS_ACCESS_KEY_ID</tt> (or <tt>AWS_ACCESS_KEY</tt>), 072 * <tt>AWS_SECRET_KEY</tt> (or <tt>AWS_SECRET_ACCESS_KEY</tt>) and <tt>AWS_SESSION_TOKEN</tt></li> 073 * <li>The ECS container credentials service (ECS, EKS, Greengrass, Fargate)</li> 074 * <li>The EC2 instance metadata service (IMDSv2)</li> 075 * </ul> 076 */ 077 public static AmazonCredentials getDefault() throws IOException { 078 if (getenv("AWS_ACCESS_KEY_ID") != null || getenv("AWS_ACCESS_KEY") != null) { 079 String accessKey = getenv("AWS_ACCESS_KEY_ID"); 080 if (accessKey == null) { 081 accessKey = getenv("AWS_ACCESS_KEY"); 082 } 083 String secretKey = getenv("AWS_SECRET_KEY"); 084 if (secretKey == null) { 085 secretKey = getenv("AWS_SECRET_ACCESS_KEY"); 086 } 087 String sessionToken = getenv("AWS_SESSION_TOKEN"); 088 089 return new AmazonCredentials(accessKey, secretKey, sessionToken); 090 } else { 091 try { 092 return new AmazonECSCredentialsClient().getCredentials(); 093 } catch (IOException ecsException) { 094 try { 095 return new AmazonIMDS2Client().getCredentials(); 096 } catch (IOException imds2Exception) { 097 ecsException.addSuppressed(imds2Exception); 098 throw ecsException; 099 } 100 } 101 } 102 } 103 104 static String getenv(String name) { 105 return System.getenv(name); 106 } 107}