1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.syncope.core.persistence.jpa.inner;
20
21 import static org.junit.jupiter.api.Assertions.assertEquals;
22 import static org.junit.jupiter.api.Assertions.assertNotNull;
23 import static org.junit.jupiter.api.Assertions.assertNull;
24 import static org.junit.jupiter.api.Assertions.assertTrue;
25
26 import java.io.ByteArrayInputStream;
27 import java.io.ByteArrayOutputStream;
28 import java.math.BigInteger;
29 import java.security.KeyPair;
30 import java.security.KeyPairGenerator;
31 import java.security.KeyStore;
32 import java.security.Signature;
33 import java.security.cert.Certificate;
34 import java.security.cert.CertificateFactory;
35 import java.util.Date;
36 import java.util.UUID;
37 import org.apache.commons.io.IOUtils;
38 import org.apache.syncope.core.persistence.api.dao.SAML2SPEntityDAO;
39 import org.apache.syncope.core.persistence.api.entity.am.SAML2SPEntity;
40 import org.apache.syncope.core.persistence.jpa.AbstractTest;
41 import org.bouncycastle.asn1.ASN1EncodableVector;
42 import org.bouncycastle.asn1.ASN1Encoding;
43 import org.bouncycastle.asn1.ASN1Integer;
44 import org.bouncycastle.asn1.DERBitString;
45 import org.bouncycastle.asn1.DERNull;
46 import org.bouncycastle.asn1.DERSequence;
47 import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
48 import org.bouncycastle.asn1.x500.X500Name;
49 import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
50 import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
51 import org.bouncycastle.asn1.x509.TBSCertificate;
52 import org.bouncycastle.asn1.x509.Time;
53 import org.bouncycastle.asn1.x509.V3TBSCertificateGenerator;
54 import org.junit.jupiter.api.Test;
55 import org.springframework.beans.factory.annotation.Autowired;
56 import org.springframework.core.io.ClassPathResource;
57 import org.springframework.transaction.annotation.Transactional;
58
59 @Transactional("Master")
60 public class SAML2SPEntityTest extends AbstractTest {
61
62 private static Certificate createSelfSignedCert(final KeyPair keyPair) throws Exception {
63 X500Name dn = new X500Name("cn=Unknown");
64 V3TBSCertificateGenerator certGen = new V3TBSCertificateGenerator();
65
66 certGen.setSerialNumber(new ASN1Integer(BigInteger.valueOf(1)));
67 certGen.setIssuer(dn);
68 certGen.setSubject(dn);
69 certGen.setStartDate(new Time(new Date(System.currentTimeMillis() - 1000L)));
70
71 Date expiration = new Date(System.currentTimeMillis() + 100000);
72 certGen.setEndDate(new Time(expiration));
73
74 AlgorithmIdentifier sigAlgID = new AlgorithmIdentifier(
75 PKCSObjectIdentifiers.sha1WithRSAEncryption, DERNull.INSTANCE);
76 certGen.setSignature(sigAlgID);
77 certGen.setSubjectPublicKeyInfo(SubjectPublicKeyInfo.getInstance(keyPair.getPublic().getEncoded()));
78
79 Signature sig = Signature.getInstance("SHA1WithRSA");
80 sig.initSign(keyPair.getPrivate());
81 sig.update(certGen.generateTBSCertificate().getEncoded(ASN1Encoding.DER));
82
83 TBSCertificate tbsCert = certGen.generateTBSCertificate();
84 ASN1EncodableVector v = new ASN1EncodableVector();
85
86 v.add(tbsCert);
87 v.add(sigAlgID);
88 v.add(new DERBitString(sig.sign()));
89
90 Certificate cert = CertificateFactory.getInstance("X.509").
91 generateCertificate(new ByteArrayInputStream(new DERSequence(v).getEncoded(ASN1Encoding.DER)));
92 cert.verify(keyPair.getPublic());
93 return cert;
94 }
95
96 @Autowired
97 private SAML2SPEntityDAO saml2SPEntityDAO;
98
99 @Test
100 public void find() throws Exception {
101 create("Syncope");
102 SAML2SPEntity entity = saml2SPEntityDAO.find("Syncope");
103 assertNotNull(entity);
104
105 entity = saml2SPEntityDAO.find(UUID.randomUUID().toString());
106 assertNull(entity);
107 }
108
109 @Test
110 public void save() throws Exception {
111 SAML2SPEntity created = create("SyncopeCreate");
112
113 KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
114 char[] pwdArray = "password".toCharArray();
115 ks.load(new ByteArrayInputStream(created.getKeystore()), pwdArray);
116 assertTrue(ks.size() > 0);
117 }
118
119 @Test
120 public void update() throws Exception {
121 SAML2SPEntity entity = create("SyncopeUpdate");
122 assertNotNull(entity);
123 entity.setKey("OtherSyncope");
124
125 entity = saml2SPEntityDAO.save(entity);
126 assertNotNull(entity);
127
128 entityManager().flush();
129
130 SAML2SPEntity found = saml2SPEntityDAO.find(entity.getKey());
131 assertNotNull(found);
132 assertEquals("OtherSyncope", found.getKey());
133 }
134
135 private SAML2SPEntity create(final String owner) throws Exception {
136 SAML2SPEntity entity = entityFactory.newEntity(SAML2SPEntity.class);
137 entity.setKey(owner);
138 entity.setMetadata(IOUtils.toByteArray(new ClassPathResource("sp-metadata.xml").getInputStream()));
139
140 KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
141 char[] pwdArray = "password".toCharArray();
142 ks.load(null, pwdArray);
143
144 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
145 keyPairGenerator.initialize(4096);
146 KeyPair keyPair = keyPairGenerator.generateKeyPair();
147 Certificate certificate = createSelfSignedCert(keyPair);
148 ks.setKeyEntry("main", keyPair.getPrivate(), "password".toCharArray(), new Certificate[] { certificate });
149
150 try (ByteArrayOutputStream fos = new ByteArrayOutputStream()) {
151 ks.store(fos, pwdArray);
152 fos.flush();
153 entity.setKeystore(fos.toByteArray());
154 }
155 assertNotNull(entity.getKeystore());
156
157 entity = saml2SPEntityDAO.save(entity);
158 assertNotNull(saml2SPEntityDAO.find(entity.getKey()));
159 return entity;
160 }
161 }