Skip to content

Commit 5180ce1

Browse files
committed
Address PR Comments
1 parent 245bd23 commit 5180ce1

File tree

2 files changed

+52
-50
lines changed

2 files changed

+52
-50
lines changed

services/signin/src/main/java/software/amazon/awssdk/services/signin/internal/EcKeyLoader.java

Lines changed: 48 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515

1616
package software.amazon.awssdk.services.signin.internal;
1717

18-
import java.io.ByteArrayInputStream;
19-
import java.io.IOException;
2018
import java.math.BigInteger;
19+
import java.nio.BufferUnderflowException;
20+
import java.nio.ByteBuffer;
2121
import java.security.AlgorithmParameters;
2222
import java.security.KeyFactory;
2323
import java.security.NoSuchAlgorithmException;
@@ -38,15 +38,18 @@
3838
@SdkInternalApi
3939
public final class EcKeyLoader {
4040

41-
public static final String SECP_256_R1_STD_NAME = "secp256r1";
42-
public static final int DER_SEQUENCE_TAG = 0x30;
43-
public static final int DER_INTEGER_TAG = 0x02;
44-
public static final int DER_OCTET_STRING_TAG = 0x04;
45-
public static final int DER_BIT_STRING_TAG = 0x03;
46-
public static final int DER_OPTIONAL_SEQ_PARAM_0 = 0xA0;
47-
public static final int DER_OPTIONAL_SEQ_PARAM_1 = 0xA1;
48-
public static final int DER_OBJECT_IDENTIFIER_TAG = 0x06;
49-
public static final int SEC1_VERSION = 1;
41+
private static final String SECP_256_R1_STD_NAME = "secp256r1";
42+
43+
private static final byte DER_SEQUENCE_TAG = 0x30;
44+
private static final byte DER_INTEGER_TAG = 0x02;
45+
private static final byte DER_OCTET_STRING_TAG = 0x04;
46+
private static final byte DER_BIT_STRING_TAG = 0x03;
47+
private static final byte DER_OPTIONAL_SEQ_PARAM_0 = (byte) 0xA0;
48+
private static final byte DER_OPTIONAL_SEQ_PARAM_1 = (byte) 0xA1;
49+
private static final byte DER_OBJECT_IDENTIFIER_TAG = 0x06;
50+
51+
private static final int SEC1_VERSION = 1;
52+
5053
// bytes for "1.2.840.10045.3.1.7" - the OID for secp256r1 aka prime256v1/NIST P-256
5154
private static byte[] SECP_256_R1_OID_BYTES = new byte[] {0x2A, (byte) 0x86, 0x48, (byte) 0xCE, 0x3D, 0x03, 0x01, 0x07};
5255

@@ -131,67 +134,65 @@ private static class ParsedEcKey {
131134
*/
132135
private static ParsedEcKey parseSec1(byte[] der) {
133136
ParsedEcKey result = new ParsedEcKey();
134-
ByteArrayInputStream in = new ByteArrayInputStream(der);
137+
ByteBuffer buffer = ByteBuffer.wrap(der);
135138
int len;
136139
try {
137-
if (in.read() != DER_SEQUENCE_TAG) {
140+
if (buffer.get() != DER_SEQUENCE_TAG) {
138141
throw new IllegalArgumentException(
139142
"Invalid SEC1 Private Key: Not a SEQUENCE");
140143
}
141-
readLength(in);
144+
readLength(buffer);
142145

143146
// validate the version
144-
if (in.read() != DER_INTEGER_TAG) {
147+
if (buffer.get() != DER_INTEGER_TAG) {
145148
throw new IllegalArgumentException(
146149
"Invalid SEC1 Private Key: Expected INTEGER");
147150
}
148-
len = readLength(in);
149-
if (len != 1 || in.read() != SEC1_VERSION) {
151+
len = readLength(buffer);
152+
if (len != 1 || buffer.get() != SEC1_VERSION) {
150153
throw new IllegalArgumentException("Invalid SEC1 Private Key: invalid version");
151154
}
152155

153156
// read private key
154-
if (in.read() != DER_OCTET_STRING_TAG) {
157+
if (buffer.get() != DER_OCTET_STRING_TAG) {
155158
throw new IllegalArgumentException(
156159
"Invalid SEC1 Private Key: Expected OCTET STRING");
157160
}
158-
len = readLength(in);
161+
len = readLength(buffer);
159162

160163
byte[] privateKeyBytes = new byte[len];
161-
in.read(privateKeyBytes);
164+
buffer.get(privateKeyBytes);
162165
result.privateScalar = new BigInteger(1, privateKeyBytes);
163166

164-
while (in.available() > 0) {
165-
int tag = in.read();
166-
if (tag == -1) {
167-
break;
168-
}
169-
len = readLength(in);
167+
while (buffer.hasRemaining()) {
168+
byte tag = buffer.get();
169+
len = readLength(buffer);
170170
if (tag == DER_OPTIONAL_SEQ_PARAM_0) { // [0] parameters (curve OID)
171-
if (in.read() != DER_OBJECT_IDENTIFIER_TAG) {
172-
throw new IOException(
171+
if (buffer.get() != DER_OBJECT_IDENTIFIER_TAG) {
172+
throw new IllegalArgumentException(
173173
"Invalid SEC1 Private Key: Expected OID");
174174
}
175-
int oidLen = readLength(in);
175+
int oidLen = readLength(buffer);
176176
byte[] oid = new byte[oidLen];
177-
in.read(oid);
177+
buffer.get(oid);
178178
result.curveOid = oid;
179179
} else if (tag == DER_OPTIONAL_SEQ_PARAM_1) { // [1] parameters public key (BIT STRING)
180-
int bitTag = in.read();
180+
byte bitTag = buffer.get();
181181
if (bitTag != DER_BIT_STRING_TAG) {
182-
throw new IOException(
182+
throw new IllegalArgumentException(
183183
"Invalid SEC1 Private Key: Expected BIT STRING");
184184
}
185-
int bitLen = readLength(in);
185+
int bitLen = readLength(buffer);
186186
byte[] bitString = new byte[bitLen];
187-
in.read(bitString);
187+
buffer.get(bitString);
188188
// First byte of BIT STRING is the unused bits count, skip it
189189
result.publicBytes = java.util.Arrays.copyOfRange(bitString, 1, bitString.length);
190190
} else {
191-
in.skip(len); // ignore unknown
191+
// ignore unknown
192+
buffer.position(buffer.position() + len);
192193
}
193194
}
194-
} catch (IOException e) {
195+
} catch (BufferUnderflowException e) {
195196
throw new IllegalArgumentException("Invalid SEC1 Private Key: failed to parse.", e);
196197
}
197198
return result;
@@ -213,37 +214,36 @@ public static byte[] pemToDer(String pem) {
213214
* Read a length from a DER byte input stream. lengths may be either a single byte (short form) or multiple bytes. If the
214215
* first bit is 0, then the remaining 7 bits give the length directly (short form). If the first bit is 1, then the next 7
215216
* bits give the number of bytes to read for the length. Eg: [0x82 0x01 0xF4] means the length is 2 bytes long (0x82) and the
216-
* length is 500 (0x01F4)
217+
* length is 500 (0x01F4).
217218
*
218-
* @param in - byte input stream to read from.
219+
* Throws BufferUnderflowException if there are insufficient bytes
220+
*
221+
* @param buffer - byte buffer to read from
219222
* @return the length
220-
* @throws IOException
221223
*/
222-
private static int readLength(ByteArrayInputStream in) throws IOException {
223-
int b = in.read();
224-
if (b < 0) {
225-
throw new IOException("Unexpected EOF while reading length");
226-
}
224+
private static int readLength(ByteBuffer buffer) {
225+
int b = buffer.get() & 0xFF; // convert signed byte to unsigned int
226+
227227
// if the high (first) bit is 0, then the length is a single byte, return it as is.
228228
if ((b & 0x80) == 0) {
229229
return b;
230230
}
231231
// remove the leading 1 bit, this should give the number of bytes for the length
232232
int num = b & 0x7F;
233233
if (num == 0) {
234-
throw new IOException("Indefinite lengths not supported");
234+
throw new IllegalArgumentException("Indefinite lengths not supported");
235235
}
236236
// limit to 4 bytes, supported keys will never have more than 4 bytes of length
237237
if (num > 4) {
238-
throw new IOException("Too many bytes in length");
238+
throw new IllegalArgumentException("Too many bytes in length");
239239
}
240240
int val = 0;
241241

242242
// construct the length by reading num bytes from the input byte stream.
243243
for (int i = 0; i < num; i++) {
244-
int nb = in.read();
244+
int nb = buffer.get() & 0xFF;
245245
if (nb < 0) {
246-
throw new IOException("Unexpected EOF in length bytes");
246+
throw new IllegalArgumentException("Unexpected EOF in length bytes");
247247
}
248248
val = (val << 8) | (nb & 0xFF);
249249
}

services/signin/src/test/java/software/amazon/awssdk/services/signin/auth/internal/EcKeyLoaderTest.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,9 @@ void invalidKey_missingPublicKey_throwsException() {
120120
}
121121

122122
private String derToPem(byte[] der) {
123-
return Base64.getEncoder().encodeToString(der);
123+
return
124+
"-----BEGIN EC PRIVATE KEY-----\n"
125+
+ Base64.getEncoder().encodeToString(der)
126+
+ "\n-----END EC PRIVATE KEY-----";
124127
}
125-
126128
}

0 commit comments

Comments
 (0)