From: Markus Pfeiffer Date: Tue, 21 Nov 2023 14:37:23 +0000 (+0100) Subject: android: Add utility that parses a PKCS#12 container and extracts a KeyPair X-Git-Tag: android-2.5.0^2~14 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=22bce57e4c4b1f3d5d9b294f160c0cc78c5566f3;p=thirdparty%2Fstrongswan.git android: Add utility that parses a PKCS#12 container and extracts a KeyPair --- diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/utils/KeyPairs.java b/src/frontends/android/app/src/main/java/org/strongswan/android/utils/KeyPairs.java new file mode 100644 index 0000000000..43c8966836 --- /dev/null +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/utils/KeyPairs.java @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2023 Relution GmbH + * + * Copyright (C) secunet Security Networks AG + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +package org.strongswan.android.utils; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.security.Key; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.UnrecoverableKeyException; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.Enumeration; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +public class KeyPairs +{ + private static final String KEYSTORE_INSTANCE = "PKCS12"; + + @NonNull + private static KeyStore toKeyStore(@NonNull byte[] bytes, @NonNull char[] password) + throws IOException, KeyStoreException, CertificateException, NoSuchAlgorithmException + { + try (final ByteArrayInputStream stream = new ByteArrayInputStream(bytes)) + { + final KeyStore keyStore = KeyStore.getInstance(KEYSTORE_INSTANCE); + keyStore.load(stream, password); + return keyStore; + } + } + + @Nullable + private static KeyPair getKeyPair( + @NonNull final KeyStore keyStore, + @NonNull final String alias, + @NonNull final char[] passwordChars) + throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException + { + final Certificate certificate = keyStore.getCertificate(alias); + if (!(certificate instanceof X509Certificate)) + { + return null; + } + + final Key key = keyStore.getKey(alias, passwordChars); + if (key == null) + { + return null; + } + return new KeyPair(certificate, (PrivateKey)key); + } + + @Nullable + private static KeyPair getKeyPair(@NonNull KeyStore keyStore, @NonNull char[] passwordChars) + throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException + { + final Enumeration aliases = keyStore.aliases(); + while (aliases.hasMoreElements()) + { + final String alias = aliases.nextElement(); + final KeyPair keyPair = getKeyPair(keyStore, alias, passwordChars); + if (keyPair != null) + { + return keyPair; + } + } + return null; + } + + @Nullable + public static KeyPair from(@NonNull final String userCertificate, @NonNull final String password) + throws IOException, KeyStoreException, CertificateException, NoSuchAlgorithmException, UnrecoverableKeyException + { + final byte[] bytes = android.util.Base64.decode(userCertificate, android.util.Base64.DEFAULT); + final char[] passwordChars = password.toCharArray(); + + final KeyStore keyStore = toKeyStore(bytes, passwordChars); + return getKeyPair(keyStore, passwordChars); + } + + private KeyPairs() {} +}