1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.syncope.core.provisioning.java.data;
20
21 import com.nimbusds.jose.JOSEException;
22 import com.nimbusds.jose.jwk.Curve;
23 import com.nimbusds.jose.jwk.ECKey;
24 import com.nimbusds.jose.jwk.JWK;
25 import com.nimbusds.jose.jwk.JWKSet;
26 import com.nimbusds.jose.jwk.KeyUse;
27 import com.nimbusds.jose.jwk.gen.RSAKeyGenerator;
28 import com.nimbusds.jose.util.JSONObjectUtils;
29 import java.security.InvalidAlgorithmParameterException;
30 import java.security.KeyPair;
31 import java.security.KeyPairGenerator;
32 import java.security.NoSuchAlgorithmException;
33 import java.security.interfaces.ECPrivateKey;
34 import java.security.interfaces.ECPublicKey;
35 import org.apache.syncope.common.lib.SyncopeClientException;
36 import org.apache.syncope.common.lib.to.OIDCJWKSTO;
37 import org.apache.syncope.common.lib.types.ClientExceptionType;
38 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
39 import org.apache.syncope.core.persistence.api.entity.am.OIDCJWKS;
40 import org.apache.syncope.core.provisioning.api.data.OIDCJWKSDataBinder;
41 import org.apache.syncope.core.spring.security.SecureRandomUtils;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44
45 public class OIDCJWKSDataBinderImpl implements OIDCJWKSDataBinder {
46
47 protected static final Logger LOG = LoggerFactory.getLogger(OIDCJWKSDataBinder.class);
48
49 protected final EntityFactory entityFactory;
50
51 public OIDCJWKSDataBinderImpl(final EntityFactory entityFactory) {
52 this.entityFactory = entityFactory;
53 }
54
55 @Override
56 public OIDCJWKSTO getOIDCJWKSTO(final OIDCJWKS jwks) {
57 return new OIDCJWKSTO.Builder().json(jwks.getJson()).key(jwks.getKey()).build();
58 }
59
60 @Override
61 public OIDCJWKS create(final String jwksKeyId, final String jwksType, final int jwksKeySize) {
62 JWK jwk;
63 try {
64 switch (jwksType.trim().toLowerCase()) {
65 case "ec":
66 KeyPairGenerator gen = KeyPairGenerator.getInstance("EC");
67 KeyPair keyPair;
68 switch (jwksKeySize) {
69 case 384:
70 gen.initialize(Curve.P_384.toECParameterSpec());
71 keyPair = gen.generateKeyPair();
72 jwk = new ECKey.Builder(Curve.P_384, (ECPublicKey) keyPair.getPublic()).
73 privateKey((ECPrivateKey) keyPair.getPrivate()).
74 keyUse(KeyUse.SIGNATURE).
75 keyID(jwksKeyId.concat("-").
76 concat(SecureRandomUtils.generateRandomUUID().toString().substring(0, 8))).
77 build();
78 break;
79
80 case 512:
81 gen.initialize(Curve.P_521.toECParameterSpec());
82 keyPair = gen.generateKeyPair();
83 jwk = new ECKey.Builder(Curve.P_521, (ECPublicKey) keyPair.getPublic()).
84 privateKey((ECPrivateKey) keyPair.getPrivate()).
85 keyUse(KeyUse.SIGNATURE).
86 keyID(jwksKeyId.concat("-").
87 concat(SecureRandomUtils.generateRandomUUID().toString().substring(0, 8))).
88 build();
89 break;
90
91 default:
92 gen.initialize(Curve.P_256.toECParameterSpec());
93 keyPair = gen.generateKeyPair();
94 jwk = new ECKey.Builder(Curve.P_256, (ECPublicKey) keyPair.getPublic()).
95 privateKey((ECPrivateKey) keyPair.getPrivate()).
96 keyUse(KeyUse.SIGNATURE).
97 keyID(jwksKeyId.concat("-").
98 concat(SecureRandomUtils.generateRandomUUID().toString().substring(0, 8))).
99 build();
100 }
101 break;
102
103 case "rsa":
104 default:
105 jwk = new RSAKeyGenerator(jwksKeySize).
106 keyUse(KeyUse.SIGNATURE).
107 keyID(jwksKeyId.concat("-").
108 concat(SecureRandomUtils.generateRandomUUID().toString().substring(0, 8))).
109 generate();
110 }
111 } catch (JOSEException | InvalidAlgorithmParameterException | NoSuchAlgorithmException e) {
112 LOG.error("Could not create OIDC JWKS", e);
113
114 SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.Unknown);
115 sce.getElements().add(e.getMessage());
116 throw sce;
117 }
118
119 OIDCJWKS jwks = entityFactory.newEntity(OIDCJWKS.class);
120 jwks.setJson(JSONObjectUtils.toJSONString(new JWKSet(jwk).toJSONObject(false)));
121 return jwks;
122 }
123 }