Skip to content

Commit

Permalink
feat: extending crypto support, sub pr4; #142;
Browse files Browse the repository at this point in the history
  • Loading branch information
smansoft committed Jan 22, 2022
1 parent 8885810 commit 05f1a65
Show file tree
Hide file tree
Showing 10 changed files with 209 additions and 102 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@
* Command example:
* java -cp bcprov-jdk15on-1.54.jar:.jar:bcpkix-jdk15on-1.54.jar:commons-cli-1.2.jar:commons-codec-1.5.jar:commons-lang-2.6.jar:jettison-1.3.jar:log4j-1.2.14.jar:oxauth-model.jar:oxauth.jar KeyGenerator -h
* <p/>
* KeyGenerator -sig_keys RS256 RS384 RS512 ES256 ES256K ES384 ES512 PS256 PS384 PS512 Ed25519 Ed448 -enc_keys RSA1_5 RSA-OAEP ECDH-ES ECDH-ES+A128KW ECDH-ES+A192KW ECDH-ES+A256KW -keystore /Users/JAVIER/tmp/mykeystore.jks -keypasswd secret -dnname "CN=Jans Auth CA Certificates" -expiration 365
* KeyGenerator -sig_keys RS256 RS384 RS512 ES256 ES256K ES384 ES512 PS256 PS384 PS512 EdDSA -enc_keys RSA1_5 RSA-OAEP RSA-OAEP-256 ECDH-ES ECDH-ES+A128KW ECDH-ES+A192KW ECDH-ES+A256KW -keystore /Users/JAVIER/tmp/mykeystore.jks -keypasswd secret -dnname "CN=Jans Auth CA Certificates" -expiration 365
* <p/>
* KeyGenerator -sig_keys RS256 RS384 RS512 ES256 ES256K ES384 ES512 PS256 PS384 PS512 Ed25519 Ed448 -ox11 https://ce.gluu.info:8443/oxeleven/rest/generateKey -expiration 365 -at xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
* KeyGenerator -sig_keys RS256 RS384 RS512 ES256 ES256K ES384 ES512 PS256 PS384 PS512 EdDSA -ox11 https://ce.gluu.info:8443/oxeleven/rest/generateKey -expiration 365 -at xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
*
* @author Javier Rojas Blum
* @author Yuriy Movchan
Expand Down Expand Up @@ -97,11 +97,11 @@ public Cli(String[] args) {
this.args = args;

Option signingKeysOption = new Option(SIGNING_KEYS, true,
"Signature keys to generate (RS256 RS384 RS512 ES256 ES256K ES384 ES512 PS256 PS384 PS512 Ed25519 Ed448).");
"Signature keys to generate (RS256 RS384 RS512 ES256 ES256K ES384 ES512 PS256 PS384 PS512 EdDSA).");
signingKeysOption.setArgs(Option.UNLIMITED_VALUES);

Option encryptionKeysOption = new Option(ENCRYPTION_KEYS, true,
"Encryption keys to generate (RSA1_5 RSA-OAEP ECDH-ES ECDH-ES+A128KW ECDH-ES+A192KW ECDH-ES+A256KW).");
"Encryption keys to generate (RSA1_5 RSA-OAEP RSA-OAEP-256 ECDH-ES ECDH-ES+A128KW ECDH-ES+A192KW ECDH-ES+A256KW).");
encryptionKeysOption.setArgs(Option.UNLIMITED_VALUES);

options.addOption(signingKeysOption);
Expand All @@ -114,6 +114,7 @@ public Cli(String[] args) {
options.addOption(EXPIRATION, true, "Expiration in days.");
options.addOption(EXPIRATION_HOURS, true, "Expiration in hours.");
options.addOption(KEY_LENGTH, true, "Key length");
options.addOption(TEST_PROP_FILE, true, "Tests property file.");
options.addOption(HELP, false, "Show help.");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,7 @@ private JSONObject generateKeySignature(Algorithm algorithm, Long expirationTime
break;
}
case ED: {
EdDSAParameterSpec edSpec = new EdDSAParameterSpec(signatureAlgorithm.getName());
EdDSAParameterSpec edSpec = new EdDSAParameterSpec(signatureAlgorithm.getCurve().getAlias());
keyGen = KeyPairGenerator.getInstance(signatureAlgorithm.getName(), "BC");
keyGen.initialize(edSpec, new SecureRandom());
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@
package io.jans.as.model.crypto;

import io.jans.as.model.crypto.signature.ECDSAPublicKey;
import io.jans.as.model.crypto.signature.EDDSAPublicKey;
import io.jans.as.model.crypto.signature.RSAPublicKey;
import io.jans.as.model.crypto.signature.SignatureAlgorithm;
import io.jans.as.model.util.StringUtils;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
import org.bouncycastle.jcajce.provider.asymmetric.edec.BCEdDSAPublicKey;
import org.bouncycastle.jcajce.provider.asymmetric.rsa.BCRSAPublicKey;
import org.bouncycastle.openssl.jcajce.JcaPEMWriter;
import org.json.JSONArray;
Expand All @@ -21,19 +23,33 @@
import java.util.Arrays;

/**
* Certificate, uses RSA, EcDSA, EdDSA.
*
* @author Javier Rojas Blum
* @version June 29, 2016
* @author Sergey Manoylo
* @version September 13, 2021
*/
public class Certificate {

private final SignatureAlgorithm signatureAlgorithm;
private final X509Certificate x509Certificate;
private SignatureAlgorithm signatureAlgorithm;
private X509Certificate x509Certificate;

/**
* Constructor.
*
* @param signatureAlgorithm Signature algorithm (RS256, RS384, RS512, ES256, ES256K, ES384, ES512, PS256, PS384, PS512, EDDSA/Ed25519).
* @param x509Certificate X509 certificate.
*/
public Certificate(SignatureAlgorithm signatureAlgorithm, X509Certificate x509Certificate) {
this.signatureAlgorithm = signatureAlgorithm;
this.x509Certificate = x509Certificate;
}

/**
* Returns Public Key from X509 Certificate.
*
* @return Public Key from X509 Certificate.
*/
public PublicKey getPublicKey() {
PublicKey publicKey = null;

Expand All @@ -46,34 +62,70 @@ public PublicKey getPublicKey() {

publicKey = new ECDSAPublicKey(signatureAlgorithm, jceecPublicKey.getQ().getXCoord().toBigInteger(),
jceecPublicKey.getQ().getYCoord().toBigInteger());
} else if (x509Certificate != null && x509Certificate.getPublicKey() instanceof BCEdDSAPublicKey) {
BCEdDSAPublicKey jceedPublicKey = (BCEdDSAPublicKey) x509Certificate.getPublicKey();

publicKey = new EDDSAPublicKey(signatureAlgorithm, jceedPublicKey.getEncoded());
}

return publicKey;
}

/**
* Returns RSA Public Key from X509 Certificate.
*
* @return RSA Public Key from X509 Certificate.
*/
public RSAPublicKey getRsaPublicKey() {
RSAPublicKey rsaPublicKey = null;

if (x509Certificate != null && x509Certificate.getPublicKey() instanceof BCRSAPublicKey) {
BCRSAPublicKey publicKey = (BCRSAPublicKey) x509Certificate.getPublicKey();

rsaPublicKey = new RSAPublicKey(publicKey.getModulus(), publicKey.getPublicExponent());
if (x509Certificate != null) {
if (x509Certificate.getPublicKey() instanceof BCRSAPublicKey) {
BCRSAPublicKey publicKey = (BCRSAPublicKey) x509Certificate.getPublicKey();
rsaPublicKey = new RSAPublicKey(publicKey.getModulus(), publicKey.getPublicExponent());
} else if (x509Certificate.getPublicKey() instanceof java.security.interfaces.RSAPublicKey) {
java.security.interfaces.RSAPublicKey publicKey = (java.security.interfaces.RSAPublicKey) x509Certificate
.getPublicKey();
rsaPublicKey = new RSAPublicKey(publicKey.getModulus(), publicKey.getPublicExponent());
}
}

return rsaPublicKey;
}

/**
* Returns ECDSA Public Key from X509 Certificate.
*
* @return ECDSA Public Key from X509 Certificate.
*/
public ECDSAPublicKey getEcdsaPublicKey() {
ECDSAPublicKey ecdsaPublicKey = null;
if (x509Certificate != null) {
if (x509Certificate.getPublicKey() instanceof BCECPublicKey) {
BCECPublicKey publicKey = (BCECPublicKey) x509Certificate.getPublicKey();
ecdsaPublicKey = new ECDSAPublicKey(signatureAlgorithm, publicKey.getQ().getXCoord().toBigInteger(),
publicKey.getQ().getYCoord().toBigInteger());
} else if (x509Certificate.getPublicKey() instanceof java.security.interfaces.ECPublicKey) {
java.security.interfaces.ECPublicKey publicKey = (java.security.interfaces.ECPublicKey) x509Certificate
.getPublicKey();
ecdsaPublicKey = new ECDSAPublicKey(signatureAlgorithm, publicKey.getW().getAffineX(),
publicKey.getW().getAffineY());
}
}
return ecdsaPublicKey;
}

if (x509Certificate != null && x509Certificate.getPublicKey() instanceof BCECPublicKey) {
BCECPublicKey publicKey = (BCECPublicKey) x509Certificate.getPublicKey();

ecdsaPublicKey = new ECDSAPublicKey(signatureAlgorithm, publicKey.getQ().getXCoord().toBigInteger(),
publicKey.getQ().getYCoord().toBigInteger());
/**
* Returns EDDSA Public Key from X509 Certificate.
*
* @return EDDSA Public Key from X509 Certificate.
*/
public EDDSAPublicKey getEddsaPublicKey() {
EDDSAPublicKey eddsaPublicKey = null;
if (x509Certificate != null && x509Certificate.getPublicKey() instanceof BCEdDSAPublicKey) {
BCEdDSAPublicKey publicKey = (BCEdDSAPublicKey) x509Certificate.getPublicKey();
eddsaPublicKey = new EDDSAPublicKey(signatureAlgorithm, publicKey.getEncoded());
}

return ecdsaPublicKey;
return eddsaPublicKey;
}

public JSONArray toJSONArray() throws JSONException {
Expand All @@ -90,13 +142,17 @@ public JSONArray toJSONArray() throws JSONException {
public String toString() {
try {
StringWriter stringWriter = new StringWriter();
try (JcaPEMWriter pemWriter = new JcaPEMWriter(stringWriter)) {
JcaPEMWriter pemWriter = new JcaPEMWriter(stringWriter);
try {
pemWriter.writeObject(x509Certificate);
pemWriter.flush();
return stringWriter.toString();
} finally {
pemWriter.close();
}
} catch (Exception e) {
return StringUtils.EMPTY_STRING;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters;
import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters;
import org.bouncycastle.crypto.params.Ed448PublicKeyParameters;
import org.bouncycastle.crypto.util.PrivateKeyInfoFactory;
import org.bouncycastle.jcajce.provider.asymmetric.edec.BCEdDSAPrivateKey;
import org.bouncycastle.jcajce.provider.asymmetric.edec.BCEdDSAPublicKey;
Expand Down Expand Up @@ -82,7 +81,7 @@ public EDDSAKeyFactory(final SignatureAlgorithm signatureAlgorithm, final String
}
this.signatureAlgorithm = signatureAlgorithm;

EdDSAParameterSpec edSpec = new EdDSAParameterSpec(signatureAlgorithm.getName());
EdDSAParameterSpec edSpec = new EdDSAParameterSpec(signatureAlgorithm.getCurve().getName());

KeyPairGenerator keyGen = KeyPairGenerator.getInstance(signatureAlgorithm.getName(), DEF_BC);
keyGen.initialize(edSpec, new SecureRandom());
Expand Down Expand Up @@ -213,23 +212,16 @@ public static EDDSAPrivateKey createEDDSAPrivateKeyFromDecodedKey(final Signatur
*/
private static byte[] getEncodedPubKey(final SignatureAlgorithm signatureAlgorithm, final byte[] decodedPublicKey) throws SignatureException {
byte[] encodedPubKey = null;
switch (signatureAlgorithm) {
case EDDSA:
case ED25519: {
encodedPubKey = new byte[Ed25519Prefix.length + Ed25519PublicKeyParameters.KEY_SIZE];
System.arraycopy(Ed25519Prefix, 0, encodedPubKey, 0, Ed25519Prefix.length);
System.arraycopy(decodedPublicKey, 0, encodedPubKey, Ed25519Prefix.length, decodedPublicKey.length);
break;
}
case ED448: {
encodedPubKey = new byte[Ed448Prefix.length + Ed448PublicKeyParameters.KEY_SIZE];
System.arraycopy(Ed448Prefix, 0, encodedPubKey, 0, Ed448Prefix.length);
System.arraycopy(decodedPublicKey, 0, encodedPubKey, Ed448Prefix.length, decodedPublicKey.length);
break;
}
default: {
throw new SignatureException(String.format("Wrong type of the signature algorithm (SignatureAlgorithm): %s", signatureAlgorithm.toString()));
}
switch(signatureAlgorithm) {
case EDDSA: {
encodedPubKey = new byte[Ed25519Prefix.length + Ed25519PublicKeyParameters.KEY_SIZE];
System.arraycopy(Ed25519Prefix, 0, encodedPubKey, 0, Ed25519Prefix.length);
System.arraycopy(decodedPublicKey, 0, encodedPubKey, Ed25519Prefix.length, decodedPublicKey.length);
break;
}
default: {
throw new SignatureException(String.format("Wrong type of the signature algorithm (SignatureAlgorithm): %s", signatureAlgorithm.toString()));
}
}
return encodedPubKey;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@
import java.util.List;

/**
* Signature Algorithms.
*
* JWS digital signature and MAC "alg" (algorithm) values
* (RFC 7518, A.1. Digital Signature/MAC Algorithm Identifier
* Cross-Reference).
*
* CFRG Elliptic Curve Diffie-Hellman (ECDH) and Signatures
* in JSON Object Signing and Encryption (JOSE) signature
* algorithm "Ed25519".
*
* @author Javier Rojas Blum
* @author Sergey Manoylo
* @version October 26, 2021
Expand All @@ -41,9 +51,7 @@ public enum SignatureAlgorithm {
PS384(SignatureAlgorithm.DEF_PS384, AlgorithmFamily.RSA, SignatureAlgorithm.DEF_SHA384WITHRSAANDMGF1, JWSAlgorithm.PS384),
PS512(SignatureAlgorithm.DEF_PS512, AlgorithmFamily.RSA, SignatureAlgorithm.DEF_SHA512WITHRSAANDMGF1, JWSAlgorithm.PS512),

ED25519(SignatureAlgorithm.DEF_ED25519, AlgorithmFamily.ED, SignatureAlgorithm.DEF_ED25519, EllipticEdvardsCurve.ED_25519, JWSAlgorithm.EdDSA),
ED448(SignatureAlgorithm.DEF_ED448, AlgorithmFamily.ED, SignatureAlgorithm.DEF_ED448, EllipticEdvardsCurve.ED_448, JWSAlgorithm.EdDSA),
EDDSA(SignatureAlgorithm.DEF_EDDDSA, AlgorithmFamily.ED, SignatureAlgorithm.DEF_ED25519, EllipticEdvardsCurve.ED_25519, JWSAlgorithm.EdDSA);
EDDSA(SignatureAlgorithm.DEF_EDDDSA, AlgorithmFamily.ED, SignatureAlgorithm.DEF_EDDDSA, EllipticEdvardsCurve.ED_25519, JWSAlgorithm.EdDSA);

public static final String DEF_HS256 = "HS256";
public static final String DEF_HS384 = "HS384";
Expand All @@ -62,8 +70,6 @@ public enum SignatureAlgorithm {
public static final String DEF_PS384 = "PS384";
public static final String DEF_PS512 = "PS512";

public static final String DEF_ED25519 = "Ed25519";
public static final String DEF_ED448 = "Ed448";
public static final String DEF_EDDDSA = "EdDSA";

public static final String DEF_HMACSHA256 = "HMACSHA256";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@ public enum Algorithm {
PS384("PS384", "id_token PS384 Sign Key", "Signature Key: RSASSA-PSS using SHA-384 and MGF1 with SHA-384", Use.SIGNATURE, AlgorithmFamily.RSA, RSAKeyFactory.DEF_KEYLENGTH),
PS512("PS512", "id_token PS512 Sign Key", "Signature Key: RSASSA-PSS using SHA-512 and MGF1 with SHA-512", Use.SIGNATURE, AlgorithmFamily.RSA, RSAKeyFactory.DEF_KEYLENGTH),

ED25519("Ed25519", "id_token Ed25519 Sign Key", "Signature Key: EDDSA using Ed25519 with SHA-512", Use.SIGNATURE, AlgorithmFamily.ED, 256),
ED448("Ed448", "id_token Ed448 Sign Key", "Signature Key: EDDSA using Ed448 with SHA-3/SHAKE256", Use.SIGNATURE, AlgorithmFamily.ED, 456),
EDDSA("EdDSA", "id_token EdDSA Sign Key", "Signature Key: EdDSA using Ed25519 with SHA-512", Use.SIGNATURE, AlgorithmFamily.ED, 256),

// Encryption
RSA1_5("RSA1_5", "id_token RSA1_5 Encryption Key", "Encryption Key: RSAES-PKCS1-v1_5",
Expand Down Expand Up @@ -133,7 +132,7 @@ public int getKeyLength() {
}

public boolean canGenerateKeys() { // based on currently supported generator, see io.jans.as.model.crypto.AuthCryptoProvider.generateKeyEncryption
return family == AlgorithmFamily.RSA || family == AlgorithmFamily.EC;
return family == AlgorithmFamily.RSA || family == AlgorithmFamily.EC || family == AlgorithmFamily.ED;
}

/**
Expand Down
Loading

0 comments on commit 05f1a65

Please sign in to comment.