Skip to content

Commit

Permalink
feat(jans-auth-server): introduced key_ops for granular map of crypto…
Browse files Browse the repository at this point in the history
… service to rotation profile #3415 (#3642)

* feat(jans-auth-server): introduced key_ops for granular map of crypto service to rotation profile #3415

* fix(jans-auth-server): fixed key rotation and added test to key generator context #3415

* minor code improvements #3415
  • Loading branch information
yuriyz authored Jan 31, 2023
1 parent 0e5778b commit 58693c5
Show file tree
Hide file tree
Showing 12 changed files with 429 additions and 157 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package io.jans.as.client.util;

import io.jans.as.model.crypto.AbstractCryptoProvider;
import io.jans.as.model.jwk.KeyOps;

import java.util.Calendar;
import java.util.GregorianCalendar;

/**
* @author Yuriy Z
*/
public class KeyGeneratorContext {

private TestPropFile testPropFile;
private AbstractCryptoProvider cryptoProvider;
private int keyLength;

private int expirationDays;
private int expirationHours;
private Calendar expiration;
private KeyOps keyOps;

public void calculateExpiration() {
Calendar calendar = new GregorianCalendar();
calendar.add(Calendar.DATE, getExpirationDays());
calendar.add(Calendar.HOUR, getExpirationHours());
this.expiration = calendar;
}

public long getExpirationForKeyOps(KeyOps keyOps) {
if (expiration == null) {
calculateExpiration();
}
if (keyOps == KeyOps.SSA) {
Calendar calendar = new GregorianCalendar();
calendar.add(Calendar.YEAR, 50);
return calendar.getTimeInMillis();
}
return expiration.getTimeInMillis();
}

public KeyOps getKeyOps() {
return keyOps;
}

public void setKeyOps(KeyOps keyOps) {
this.keyOps = keyOps;
}

public Calendar getExpiration() {
return expiration;
}

public void setExpiration(Calendar expiration) {
this.expiration = expiration;
}

public int getKeyLength() {
return keyLength;
}

public void setKeyLength(int keyLength) {
this.keyLength = keyLength;
}

public TestPropFile getTestPropFile() {
return testPropFile;
}

public void setTestPropFile(TestPropFile testPropFile) {
this.testPropFile = testPropFile;
}

public AbstractCryptoProvider getCryptoProvider() {
return cryptoProvider;
}

public void setCryptoProvider(AbstractCryptoProvider cryptoProvider) {
this.cryptoProvider = cryptoProvider;
}

public int getExpirationDays() {
return expirationDays;
}

public void setExpirationDays(int expirationDays) {
this.expirationDays = expirationDays;
}

public int getExpirationHours() {
return expirationHours;
}

public void setExpirationHours(int expirationHours) {
this.expirationHours = expirationHours;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package io.jans.as.client.util;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.lang.StringUtils;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
* @author Yuriy Z
*/
public class TestPropFile {

private static final String TEST_PROP_FILE = "test_prop_file";

private String propFile;

private List<String> records = new ArrayList<>();

public TestPropFile(String propFile) {
this.propFile = propFile;
}

public static TestPropFile create(CommandLine cmd) {
if (cmd.hasOption(TEST_PROP_FILE)) {
return new TestPropFile(cmd.getOptionValue(TEST_PROP_FILE));
}
return new TestPropFile(null);
}

public boolean isEmpty() {
return StringUtils.isBlank(propFile);
}

public boolean shouldGenerate() {
return StringUtils.isNotBlank(propFile);
}

public void add(String record) {
if (shouldGenerate())
records.add(record);
}

public void generate() throws IOException {
if (isEmpty()) {
return;
}

try (FileOutputStream fosTestPropFile = new FileOutputStream(propFile)) {
for (String rec : records) {
fosTestPropFile.write(rec.getBytes());
fosTestPropFile.write("\n".getBytes());
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package io.jans.as.client.util;

import io.jans.as.model.jwk.KeyOps;
import org.testng.annotations.Test;

import java.util.Calendar;

import static org.testng.Assert.assertTrue;

/**
* @author Yuriy Z
*/
public class KeyGeneratorContextTest {

@Test
public void getExpirationForKeyOps_forConnectKeyOps_shouldReturnPassedExpiration() {
KeyGeneratorContext context = new KeyGeneratorContext();
context.setExpirationHours(1);

final long expirationForKeyOps = context.getExpirationForKeyOps(KeyOps.CONNECT);

assertTrue(expirationForKeyOps < futureIn2Hours());
}

@Test
public void getExpirationForKeyOps_forSSAKeyOps_shouldReturnExpirationFarInFuture() {
KeyGeneratorContext context = new KeyGeneratorContext();
context.setExpirationHours(1);

final long expirationForKeyOps = context.getExpirationForKeyOps(KeyOps.SSA);

assertTrue(expirationForKeyOps > futureIn2Hours());
}

private long futureIn2Hours() {
Calendar future2hours = Calendar.getInstance();
future2hours.add(2, Calendar.HOUR_OF_DAY);
return future2hours.getTimeInMillis();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,7 @@
import io.jans.as.model.crypto.signature.SignatureAlgorithm;
import io.jans.as.model.exception.CryptoProviderException;
import io.jans.as.model.exception.InvalidParameterException;
import io.jans.as.model.jwk.Algorithm;
import io.jans.as.model.jwk.JSONWebKey;
import io.jans.as.model.jwk.JSONWebKeySet;
import io.jans.as.model.jwk.JWKParameter;
import io.jans.as.model.jwk.Use;
import io.jans.as.model.jwk.*;
import io.jans.as.model.util.Base64Util;
import io.jans.eleven.model.JwksRequestParam;
import io.jans.eleven.model.KeyRequestParam;
Expand All @@ -26,26 +22,13 @@
import org.json.JSONObject;

import java.math.BigInteger;
import java.security.AlgorithmParameters;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.ECParameterSpec;
import java.security.spec.ECPoint;
import java.security.spec.ECPublicKeySpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.InvalidParameterSpecException;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.security.*;
import java.security.spec.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.TimeZone;
import java.util.*;

/**
* @author Javier Rojas Blum
Expand All @@ -66,6 +49,8 @@ public abstract class AbstractCryptoProvider {

public abstract JSONObject generateKey(Algorithm algorithm, Long expirationTime, int keyLength) throws CryptoProviderException;

public abstract JSONObject generateKey(Algorithm algorithm, Long expirationTime, int keyLength, KeyOps keyOps) throws CryptoProviderException;

public abstract String sign(String signingInput, String keyId, String sharedSecret, SignatureAlgorithm signatureAlgorithm) throws CryptoProviderException;

public abstract boolean verifySignature(String signingInput, String encodedSignature, String keyId, JSONObject jwks, String sharedSecret, SignatureAlgorithm signatureAlgorithm) throws CryptoProviderException;
Expand Down
Loading

0 comments on commit 58693c5

Please sign in to comment.