Skip to content

Commit fc4b643

Browse files
committed
JCE: add WKS test for concurrent access to engineGetCertificateAlias()
1 parent 86a7f47 commit fc4b643

File tree

1 file changed

+166
-0
lines changed

1 file changed

+166
-0
lines changed

src/test/java/com/wolfssl/provider/jce/test/WolfSSLKeyStoreTest.java

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1832,5 +1832,171 @@ public void testStoreToByteArrayThreaded()
18321832
}
18331833
}
18341834
}
1835+
1836+
/**
1837+
* Test concurrent access to engineGetCertificateAlias() while other
1838+
* threads are modifying the same KeyStore instance via setKeyEntry()
1839+
* and setCertificateEntry().
1840+
*/
1841+
@Test
1842+
public void testGetCertificateAliasConcurrent()
1843+
throws KeyStoreException, IOException, FileNotFoundException,
1844+
NoSuchProviderException, NoSuchAlgorithmException,
1845+
CertificateException, InvalidKeySpecException,
1846+
UnrecoverableKeyException, InterruptedException {
1847+
1848+
int numThreads = 10;
1849+
int iterationsPerThread = 100;
1850+
final KeyStore store = KeyStore.getInstance(storeType,
1851+
storeProvider);
1852+
final LinkedBlockingQueue<Integer> results =
1853+
new LinkedBlockingQueue<>();
1854+
final CountDownLatch startLatch = new CountDownLatch(1);
1855+
final CountDownLatch doneLatch = new CountDownLatch(numThreads);
1856+
1857+
/* Initialize KeyStore with some initial entries */
1858+
store.load(null, null);
1859+
store.setKeyEntry("initialKey", serverKeyRsa,
1860+
storePass.toCharArray(), rsaServerChain);
1861+
store.setCertificateEntry("initialCert", serverCertRsa);
1862+
1863+
/* Create thread pool */
1864+
ExecutorService executor = Executors.newFixedThreadPool(numThreads);
1865+
1866+
/* Start reader threads that call getCertificateAlias() */
1867+
for (int i = 0; i < numThreads / 2; i++) {
1868+
final int threadId = i;
1869+
executor.submit(new Runnable() {
1870+
@Override
1871+
public void run() {
1872+
try {
1873+
/* Wait for all threads to be ready */
1874+
startLatch.await();
1875+
1876+
for (int j = 0; j < iterationsPerThread; j++) {
1877+
/* Look up alias for existing certificate */
1878+
String alias = store.getCertificateAlias(
1879+
serverCertRsa);
1880+
if (alias == null) {
1881+
/* Certificate should exist, either as
1882+
* initialCert or in a key entry chain */
1883+
results.add(1);
1884+
return;
1885+
}
1886+
1887+
/* Verify alias is valid */
1888+
if (!alias.equals("initialCert") &&
1889+
!alias.startsWith("writerKey")) {
1890+
results.add(1);
1891+
return;
1892+
}
1893+
1894+
/* Look up alias for certificate that might
1895+
* be added/removed by writers */
1896+
alias = store.getCertificateAlias(
1897+
clientCertRsa);
1898+
/* Result can be null or valid alias, both OK */
1899+
if (alias != null &&
1900+
!alias.startsWith("writerCert")) {
1901+
results.add(1);
1902+
return;
1903+
}
1904+
}
1905+
1906+
/* Success */
1907+
results.add(0);
1908+
1909+
} catch (Exception e) {
1910+
e.printStackTrace();
1911+
results.add(1);
1912+
1913+
} finally {
1914+
doneLatch.countDown();
1915+
}
1916+
}
1917+
});
1918+
}
1919+
1920+
/* Start writer threads that modify KeyStore */
1921+
for (int i = numThreads / 2; i < numThreads; i++) {
1922+
final int threadId = i;
1923+
executor.submit(new Runnable() {
1924+
@Override
1925+
public void run() {
1926+
try {
1927+
/* Wait for all threads to be ready */
1928+
startLatch.await();
1929+
1930+
for (int j = 0; j < iterationsPerThread; j++) {
1931+
String keyAlias = "writerKey" + threadId +
1932+
"_" + j;
1933+
String certAlias = "writerCert" + threadId +
1934+
"_" + j;
1935+
1936+
/* Add key entry */
1937+
store.setKeyEntry(keyAlias, serverKeyRsa,
1938+
storePass.toCharArray(), rsaServerChain);
1939+
1940+
/* Add certificate entry */
1941+
store.setCertificateEntry(certAlias,
1942+
clientCertRsa);
1943+
1944+
/* Delete some entries periodically */
1945+
if (j % 10 == 0 && j > 0) {
1946+
String oldKeyAlias = "writerKey" + threadId +
1947+
"_" + (j - 10);
1948+
String oldCertAlias = "writerCert" +
1949+
threadId + "_" + (j - 10);
1950+
try {
1951+
store.deleteEntry(oldKeyAlias);
1952+
store.deleteEntry(oldCertAlias);
1953+
} catch (KeyStoreException e) {
1954+
/* Entry might not exist, ignore */
1955+
}
1956+
}
1957+
}
1958+
1959+
/* Success */
1960+
results.add(0);
1961+
1962+
} catch (Exception e) {
1963+
e.printStackTrace();
1964+
results.add(1);
1965+
1966+
} finally {
1967+
doneLatch.countDown();
1968+
}
1969+
}
1970+
});
1971+
}
1972+
1973+
/* Start all threads simultaneously */
1974+
startLatch.countDown();
1975+
1976+
/* Wait for all threads to complete */
1977+
doneLatch.await();
1978+
1979+
/* Shutdown executor */
1980+
executor.shutdown();
1981+
1982+
/* Check results - all threads should have succeeded */
1983+
assertEquals("Expected " + numThreads + " results",
1984+
numThreads, results.size());
1985+
1986+
Iterator<Integer> listIterator = results.iterator();
1987+
while (listIterator.hasNext()) {
1988+
Integer cur = listIterator.next();
1989+
if (cur != 0) {
1990+
fail("Threading error in concurrent " +
1991+
"getCertificateAlias test");
1992+
}
1993+
}
1994+
1995+
/* Verify KeyStore is still in valid state */
1996+
assertNotNull(store.getCertificate("initialCert"));
1997+
Certificate[] chain = store.getCertificateChain("initialKey");
1998+
assertNotNull(chain);
1999+
assertTrue(chain.length > 0);
2000+
}
18352001
}
18362002

0 commit comments

Comments
 (0)