Skip to content

Commit

Permalink
Generalize public key reading in the JWT authenticator (opensearch-pr…
Browse files Browse the repository at this point in the history
…oject#4833)

Signed-off-by: Craig Perkins <[email protected]>
  • Loading branch information
cwperks authored Oct 23, 2024
1 parent 8b71209 commit eb7f821
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 25 deletions.
4 changes: 2 additions & 2 deletions src/main/java/org/opensearch/security/util/KeyUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ public JwtParserBuilder run() {
} else {
try {
PublicKey key = null;

final String minimalKeyFormat = signingKey.replace("-----BEGIN PUBLIC KEY-----\n", "")
final String minimalKeyFormat = signingKey.replaceAll("\\r|\\n", "")
.replace("-----BEGIN PUBLIC KEY-----", "")
.replace("-----END PUBLIC KEY-----", "")
.trim();
final byte[] decoded = Base64.getDecoder().decode(minimalKeyFormat);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -389,35 +389,68 @@ public void testNbf() throws Exception {

@Test
public void testRS256() throws Exception {

KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(2048);
KeyPair pair = keyGen.generateKeyPair();
PrivateKey priv = pair.getPrivate();
PublicKey pub = pair.getPublic();

String jwsToken = Jwts.builder().setSubject("Leonard McCoy").signWith(priv, SignatureAlgorithm.RS256).compact();
Settings settings = Settings.builder()
.put(
"signing_key",
"-----BEGIN PUBLIC KEY-----\n" + BaseEncoding.base64().encode(pub.getEncoded()) + "-----END PUBLIC KEY-----"
)
.build();
String signingKey = "-----BEGIN PUBLIC KEY-----\n" + BaseEncoding.base64().encode(pub.getEncoded()) + "-----END PUBLIC KEY-----";
AuthCredentials creds = testJwtAuthenticationWithSigningKey(signingKey, jwsToken);

HTTPJwtAuthenticator jwtAuth = new HTTPJwtAuthenticator(settings, null);
Map<String, String> headers = new HashMap<String, String>();
headers.put("Authorization", "Bearer " + jwsToken);
Assert.assertNotNull(creds);
assertThat(creds.getUsername(), is("Leonard McCoy"));
assertThat(creds.getBackendRoles().size(), is(0));
}

AuthCredentials creds = jwtAuth.extractCredentials(
new FakeRestRequest(headers, new HashMap<String, String>()).asSecurityRequest(),
null
);
private static String formatKeyWithNewlines(String keyAsString) {
StringBuilder result = new StringBuilder();
int lineLength = 64;
int length = keyAsString.length();

for (int i = 0; i < length; i += lineLength) {
if (i + lineLength < length) {
result.append(keyAsString, i, i + lineLength);
} else {
result.append(keyAsString.substring(i));
}
result.append("\n");
}

return result.toString().trim();
}

@Test
public void testRS256WithNewlines() throws Exception {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(2048);
KeyPair pair = keyGen.generateKeyPair();
PrivateKey priv = pair.getPrivate();
PublicKey pub = pair.getPublic();

String jwsToken = Jwts.builder().setSubject("Leonard McCoy").signWith(priv, SignatureAlgorithm.RS256).compact();

String signingKey = "-----BEGIN PUBLIC KEY-----\n"
+ formatKeyWithNewlines(BaseEncoding.base64().encode(pub.getEncoded()))
+ "\n-----END PUBLIC KEY-----";
AuthCredentials creds = testJwtAuthenticationWithSigningKey(signingKey, jwsToken);

Assert.assertNotNull(creds);
assertThat(creds.getUsername(), is("Leonard McCoy"));
assertThat(creds.getBackendRoles().size(), is(0));
}

private AuthCredentials testJwtAuthenticationWithSigningKey(String signingKey, String jwsToken) throws NoSuchAlgorithmException {
Settings settings = Settings.builder().put("signing_key", signingKey).build();

HTTPJwtAuthenticator jwtAuth = new HTTPJwtAuthenticator(settings, null);
Map<String, String> headers = new HashMap<String, String>();
headers.put("Authorization", "Bearer " + jwsToken);

return jwtAuth.extractCredentials(new FakeRestRequest(headers, new HashMap<String, String>()).asSecurityRequest(), null);
}

@Test
public void testES512() throws Exception {

Expand All @@ -427,17 +460,10 @@ public void testES512() throws Exception {
PrivateKey priv = pair.getPrivate();
PublicKey pub = pair.getPublic();

Settings settings = Settings.builder().put("signing_key", BaseEncoding.base64().encode(pub.getEncoded())).build();
String signingKey = BaseEncoding.base64().encode(pub.getEncoded());
String jwsToken = Jwts.builder().setSubject("Leonard McCoy").signWith(priv, SignatureAlgorithm.ES512).compact();

HTTPJwtAuthenticator jwtAuth = new HTTPJwtAuthenticator(settings, null);
Map<String, String> headers = new HashMap<String, String>();
headers.put("Authorization", jwsToken);

AuthCredentials creds = jwtAuth.extractCredentials(
new FakeRestRequest(headers, new HashMap<String, String>()).asSecurityRequest(),
null
);
AuthCredentials creds = testJwtAuthenticationWithSigningKey(signingKey, jwsToken);

Assert.assertNotNull(creds);
assertThat(creds.getUsername(), is("Leonard McCoy"));
Expand Down

0 comments on commit eb7f821

Please sign in to comment.