org.eclipse.osgi.internal.permadmin.SecurityAdmin Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aspectjtools Show documentation
Show all versions of aspectjtools Show documentation
Tools from the AspectJ project
/*******************************************************************************
* Copyright (c) 2008, 2020 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.osgi.internal.permadmin;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.AccessControlContext;
import java.security.AllPermission;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Permission;
import java.security.PermissionCollection;
import java.security.Principal;
import java.security.ProtectionDomain;
import java.security.PublicKey;
import java.security.SignatureException;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateExpiredException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.osgi.internal.framework.EquinoxBundle;
import org.eclipse.osgi.storage.PermissionData;
import org.osgi.framework.AdminPermission;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.Version;
import org.osgi.service.condpermadmin.ConditionInfo;
import org.osgi.service.condpermadmin.ConditionalPermissionAdmin;
import org.osgi.service.condpermadmin.ConditionalPermissionInfo;
import org.osgi.service.condpermadmin.ConditionalPermissionUpdate;
import org.osgi.service.permissionadmin.PermissionAdmin;
import org.osgi.service.permissionadmin.PermissionInfo;
public final class SecurityAdmin implements PermissionAdmin, ConditionalPermissionAdmin {
private static final PermissionCollection DEFAULT_DEFAULT;
static {
AllPermission allPerm = new AllPermission();
DEFAULT_DEFAULT = allPerm.newPermissionCollection();
if (DEFAULT_DEFAULT != null)
DEFAULT_DEFAULT.add(allPerm);
}
// Base implied permissions for all bundles
private static final String OSGI_BASE_IMPLIED_PERMISSIONS = "implied.permissions"; //$NON-NLS-1$
private static final String ADMIN_IMPLIED_ACTIONS = AdminPermission.RESOURCE + ',' + AdminPermission.METADATA + ','
+ AdminPermission.CLASS + ',' + AdminPermission.CONTEXT;
private static final PermissionInfo[] EMPTY_PERM_INFO = new PermissionInfo[0];
/* @GuardedBy(lock) */
private final PermissionAdminTable permAdminTable = new PermissionAdminTable();
/* @GuardedBy(lock) */
private SecurityTable condAdminTable;
/* @GuardedBy(lock) */
private PermissionInfoCollection permAdminDefaults;
/* @GuardedBy(lock) */
private long timeStamp = 0;
/* @GuardedBy(lock) */
private long nextID = System.currentTimeMillis();
/* @GuardedBy(lock) */
private final PermissionData permissionStorage;
private final Object lock = new Object();
// private final EquinoxContainer container;
private final PermissionInfo[] impliedPermissionInfos;
private final EquinoxSecurityManager supportedSecurityManager;
public SecurityAdmin(EquinoxSecurityManager supportedSecurityManager, PermissionData permissionStorage) {
this.supportedSecurityManager = supportedSecurityManager;
this.permissionStorage = permissionStorage;
this.impliedPermissionInfos = SecurityAdmin
.getPermissionInfos(getClass().getResource(OSGI_BASE_IMPLIED_PERMISSIONS));
String[] encodedDefaultInfos = permissionStorage.getPermissionData(null);
PermissionInfo[] defaultInfos = getPermissionInfos(encodedDefaultInfos);
if (defaultInfos != null)
permAdminDefaults = new PermissionInfoCollection(defaultInfos);
String[] locations = permissionStorage.getLocations();
if (locations != null) {
for (String location : locations) {
String[] encodedLocationInfos = permissionStorage.getPermissionData(location);
if (encodedLocationInfos != null) {
PermissionInfo[] locationInfos = getPermissionInfos(encodedLocationInfos);
permAdminTable.setPermissions(location, locationInfos);
}
}
}
String[] encodedCondPermInfos = permissionStorage.getConditionalPermissionInfos();
if (encodedCondPermInfos == null)
condAdminTable = new SecurityTable(this, new SecurityRow[0]);
else {
SecurityRow[] rows = new SecurityRow[encodedCondPermInfos.length];
try {
for (int i = 0; i < rows.length; i++)
rows[i] = SecurityRow.createSecurityRow(this, encodedCondPermInfos[i]);
} catch (IllegalArgumentException e) {
// TODO should log
// bad format persisted in storage; start clean
rows = new SecurityRow[0];
}
condAdminTable = new SecurityTable(this, rows);
}
}
private static PermissionInfo[] getPermissionInfos(String[] encodedInfos) {
if (encodedInfos == null)
return null;
PermissionInfo[] results = new PermissionInfo[encodedInfos.length];
for (int i = 0; i < results.length; i++)
results[i] = new PermissionInfo(encodedInfos[i]);
return results;
}
boolean checkPermission(Permission permission, BundlePermissions bundlePermissions) {
// check permissions by location
PermissionInfoCollection locationCollection;
SecurityTable curCondAdminTable;
PermissionInfoCollection curPermAdminDefaults;
// save off the current state of the world while holding the lock
synchronized (lock) {
// get location the hard way to avoid permission check
Bundle bundle = bundlePermissions.getBundle();
locationCollection = bundle instanceof EquinoxBundle
? permAdminTable.getCollection(((EquinoxBundle) bundle).getModule().getLocation())
: null;
curCondAdminTable = condAdminTable;
curPermAdminDefaults = permAdminDefaults;
}
if (locationCollection != null)
return locationCollection.implies(bundlePermissions, permission);
// if conditional admin table is empty the fall back to defaults
if (curCondAdminTable.isEmpty())
return curPermAdminDefaults != null ? curPermAdminDefaults.implies(permission)
: DEFAULT_DEFAULT.implies(permission);
// check the condition table
int result = curCondAdminTable.evaluate(bundlePermissions, permission);
if ((result & SecurityTable.GRANTED) != 0)
return true;
if ((result & SecurityTable.DENIED) != 0)
return false;
if ((result & SecurityTable.POSTPONED) != 0)
return true;
return false;
}
@Override
public PermissionInfo[] getDefaultPermissions() {
synchronized (lock) {
if (permAdminDefaults == null)
return null;
return permAdminDefaults.getPermissionInfos();
}
}
@Override
public String[] getLocations() {
synchronized (lock) {
String[] results = permAdminTable.getLocations();
return results.length == 0 ? null : results;
}
}
@Override
public PermissionInfo[] getPermissions(String location) {
synchronized (lock) {
return permAdminTable.getPermissions(location);
}
}
@Override
public void setDefaultPermissions(PermissionInfo[] permissions) {
checkAllPermission();
synchronized (lock) {
if (permissions == null)
permAdminDefaults = null;
else
permAdminDefaults = new PermissionInfoCollection(permissions);
permissionStorage.setPermissionData(null, getEncodedPermissionInfos(permissions));
}
}
private static void checkAllPermission() {
SecurityManager sm = System.getSecurityManager();
if (sm != null)
sm.checkPermission(new AllPermission());
}
private static String[] getEncodedPermissionInfos(PermissionInfo[] permissions) {
if (permissions == null)
return null;
String[] encoded = new String[permissions.length];
for (int i = 0; i < encoded.length; i++)
encoded[i] = permissions[i].getEncoded();
return encoded;
}
@Override
public void setPermissions(String location, PermissionInfo[] permissions) {
checkAllPermission();
synchronized (lock) {
permAdminTable.setPermissions(location, permissions);
permissionStorage.setPermissionData(location, getEncodedPermissionInfos(permissions));
}
}
void delete(SecurityRow securityRow, boolean firstTry) {
ConditionalPermissionUpdate update = newConditionalPermissionUpdate();
List rows = update.getConditionalPermissionInfos();
for (Iterator iRows = rows.iterator(); iRows.hasNext();) {
ConditionalPermissionInfo info = iRows.next();
if (securityRow.getName().equals(info.getName())) {
iRows.remove();
synchronized (lock) {
if (!update.commit()) {
if (firstTry)
// try again
delete(securityRow, false);
}
}
break;
}
}
}
/**
* @deprecated
*/
@Override
public ConditionalPermissionInfo addConditionalPermissionInfo(ConditionInfo[] conds, PermissionInfo[] perms) {
return setConditionalPermissionInfo(null, conds, perms, true);
}
@Override
public ConditionalPermissionInfo newConditionalPermissionInfo(String name, ConditionInfo[] conditions,
PermissionInfo[] permissions, String decision) {
return new SecurityRowSnapShot(name, conditions, permissions, decision);
}
@Override
public ConditionalPermissionInfo newConditionalPermissionInfo(String encoded) {
return SecurityRow.createSecurityRowSnapShot(encoded);
}
@Override
public ConditionalPermissionUpdate newConditionalPermissionUpdate() {
synchronized (lock) {
return new SecurityTableUpdate(this, condAdminTable.getRows(), timeStamp);
}
}
@Override
public AccessControlContext getAccessControlContext(String[] signers) {
return new AccessControlContext(
new ProtectionDomain[] { createProtectionDomain(createMockBundle(signers), this) });
}
/**
* @deprecated
*/
@Override
public ConditionalPermissionInfo getConditionalPermissionInfo(String name) {
synchronized (lock) {
return condAdminTable.getRow(name);
}
}
/**
* @deprecated
*/
@Override
public Enumeration getConditionalPermissionInfos() {
// could implement our own Enumeration, but we don't care about performance
// here. Just do something simple:
synchronized (lock) {
SecurityRow[] rows = condAdminTable.getRows();
List vRows = new ArrayList<>(rows.length);
Collections.addAll(vRows, rows);
return Collections.enumeration(vRows);
}
}
/**
* @deprecated
*/
@Override
public ConditionalPermissionInfo setConditionalPermissionInfo(String name, ConditionInfo[] conds,
PermissionInfo[] perms) {
return setConditionalPermissionInfo(name, conds, perms, true);
}
private ConditionalPermissionInfo setConditionalPermissionInfo(String name, ConditionInfo[] conds,
PermissionInfo[] perms, boolean firstTry) {
ConditionalPermissionUpdate update = newConditionalPermissionUpdate();
List rows = update.getConditionalPermissionInfos();
ConditionalPermissionInfo newInfo = newConditionalPermissionInfo(name, conds, perms,
ConditionalPermissionInfo.ALLOW);
int index = -1;
if (name != null) {
for (int i = 0; i < rows.size() && index < 0; i++) {
ConditionalPermissionInfo info = rows.get(i);
if (name.equals(info.getName())) {
index = i;
}
}
}
if (index < 0) {
// must always add to the beginning (bug 303930)
rows.add(0, newInfo);
index = 0;
} else {
rows.set(index, newInfo);
}
synchronized (lock) {
if (!update.commit()) {
if (firstTry)
// try again
setConditionalPermissionInfo(name, conds, perms, false);
}
return condAdminTable.getRow(index);
}
}
boolean commit(List rows, long updateStamp) {
checkAllPermission();
synchronized (lock) {
if (updateStamp != timeStamp)
return false;
SecurityRow[] newRows = new SecurityRow[rows.size()];
Collection names = new ArrayList<>();
for (int i = 0; i < newRows.length; i++) {
Object rowObj = rows.get(i);
if (!(rowObj instanceof ConditionalPermissionInfo))
throw new IllegalStateException(
"Invalid type \"" + rowObj.getClass().getName() + "\" at row: " + i); //$NON-NLS-1$//$NON-NLS-2$
ConditionalPermissionInfo infoBaseRow = (ConditionalPermissionInfo) rowObj;
String name = infoBaseRow.getName();
if (name == null)
name = generateName();
if (names.contains(name))
throw new IllegalStateException("Duplicate name \"" + name + "\" at row: " + i); //$NON-NLS-1$//$NON-NLS-2$
names.add(name);
newRows[i] = new SecurityRow(this, name, infoBaseRow.getConditionInfos(),
infoBaseRow.getPermissionInfos(), infoBaseRow.getAccessDecision());
}
condAdminTable = new SecurityTable(this, newRows);
permissionStorage.saveConditionalPermissionInfos(condAdminTable.getEncodedRows());
timeStamp += 1;
return true;
}
}
/* GuardedBy(lock) */
private String generateName() {
return "generated_" + Long.toString(nextID++); //$NON-NLS-1$ ;
}
public ProtectionDomain createProtectionDomain(Bundle bundle) {
return createProtectionDomain(bundle, this);
}
private ProtectionDomain createProtectionDomain(Bundle bundle, SecurityAdmin sa) {
PermissionInfoCollection impliedPermissions = getImpliedPermission(bundle);
URL permEntry = null;
try {
permEntry = bundle.getEntry("OSGI-INF/permissions.perm"); //$NON-NLS-1$
} catch (IllegalStateException e) {
// bundle may be uninstalled
}
PermissionInfo[] restrictedInfos = getFileRelativeInfos(SecurityAdmin.getPermissionInfos(permEntry), bundle);
PermissionInfoCollection restrictedPermissions = restrictedInfos == null ? null
: new PermissionInfoCollection(restrictedInfos);
BundlePermissions bundlePermissions = new BundlePermissions(bundle, sa, impliedPermissions,
restrictedPermissions);
return new ProtectionDomain(null, bundlePermissions);
}
private PermissionInfoCollection getImpliedPermission(Bundle bundle) {
if (impliedPermissionInfos == null)
return null;
// create the implied AdminPermission actions for this bundle
PermissionInfo impliedAdminPermission = new PermissionInfo(AdminPermission.class.getName(),
"(id=" + bundle.getBundleId() + ")", ADMIN_IMPLIED_ACTIONS); //$NON-NLS-1$ //$NON-NLS-2$
PermissionInfo[] bundleImpliedInfos = new PermissionInfo[impliedPermissionInfos.length + 1];
System.arraycopy(impliedPermissionInfos, 0, bundleImpliedInfos, 0, impliedPermissionInfos.length);
bundleImpliedInfos[impliedPermissionInfos.length] = impliedAdminPermission;
return new PermissionInfoCollection(getFileRelativeInfos(bundleImpliedInfos, bundle));
}
private PermissionInfo[] getFileRelativeInfos(PermissionInfo[] permissionInfos, Bundle bundle) {
if (permissionInfos == null)
return permissionInfos;
PermissionInfo[] results = new PermissionInfo[permissionInfos.length];
for (int i = 0; i < permissionInfos.length; i++) {
results[i] = permissionInfos[i];
if (PermissionInfoCollection.FILE_PERMISSION_NAME.equals(permissionInfos[i].getType())) {
if (!PermissionInfoCollection.ALL_FILES.equals(permissionInfos[i].getName())) {
File file = new File(permissionInfos[i].getName());
if (!file.isAbsolute()) { // relative name
try {
File target = bundle.getDataFile(permissionInfos[i].getName());
if (target != null)
results[i] = new PermissionInfo(permissionInfos[i].getType(), target.getPath(),
permissionInfos[i].getActions());
} catch (IllegalStateException e) {
// can happen if the bundle has been uninstalled;
// we just keep the original permission in this case.
}
}
}
}
}
return results;
}
public void clearCaches() {
PermissionInfoCollection[] permAdminCollections;
SecurityRow[] condAdminRows;
synchronized (lock) {
permAdminCollections = permAdminTable.getCollections();
condAdminRows = condAdminTable.getRows();
}
for (PermissionInfoCollection permAdminCollection : permAdminCollections) {
permAdminCollection.clearPermissionCache();
}
for (SecurityRow condAdminRow : condAdminRows) {
condAdminRow.clearCaches();
}
condAdminTable.clearEvaluationCache();
}
EquinoxSecurityManager getSupportedSecurityManager() {
return supportedSecurityManager != null ? supportedSecurityManager : getSupportedSystemSecurityManager();
}
static private EquinoxSecurityManager getSupportedSystemSecurityManager() {
try {
EquinoxSecurityManager equinoxManager = (EquinoxSecurityManager) System.getSecurityManager();
return equinoxManager != null && equinoxManager.inCheckPermission() ? equinoxManager : null;
} catch (ClassCastException e) {
return null;
}
}
private static PermissionInfo[] getPermissionInfos(URL resource) {
if (resource == null)
return null;
PermissionInfo[] info = EMPTY_PERM_INFO;
List permissions = new ArrayList<>();
try (DataInputStream in = new DataInputStream(resource.openStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))) {
while (true) {
String line = reader.readLine();
if (line == null) /* EOF */
break;
line = line.trim();
if ((line.length() == 0) || line.startsWith("#") || line.startsWith("//")) /* comments *///$NON-NLS-1$ //$NON-NLS-2$
continue;
try {
permissions.add(new PermissionInfo(line));
} catch (IllegalArgumentException iae) {
/* incorrectly encoded permission */
// TODO used to publish an event here
}
}
int size = permissions.size();
if (size > 0)
info = permissions.toArray(new PermissionInfo[size]);
} catch (IOException e) {
// do nothing
}
return info;
}
private static Bundle createMockBundle(String[] signers) {
Map> signersMap = new HashMap<>();
for (String signer : signers) {
List chain = parseDNchain(signer);
List signersList = new ArrayList<>();
Principal subject = null, issuer = null;
X509Certificate first = null;
for (Iterator iChain = chain.iterator(); iChain.hasNext();) {
subject = issuer == null ? new MockPrincipal(iChain.next()) : issuer;
issuer = iChain.hasNext() ? new MockPrincipal(iChain.next()) : subject;
X509Certificate cert = new MockX509Certificate(subject, issuer);
if (first == null)
first = cert;
signersList.add(cert);
}
if (subject != issuer)
signersList.add(new MockX509Certificate(issuer, issuer));
signersMap.put(first, signersList);
}
return new MockBundle(signersMap);
}
static class MockBundle implements Bundle {
private final Map> signers;
MockBundle(Map> signers) {
this.signers = signers;
}
@Override
public Enumeration findEntries(String path, String filePattern, boolean recurse) {
return null;
}
@Override
public BundleContext getBundleContext() {
return null;
}
@Override
public long getBundleId() {
return -1;
}
@Override
public URL getEntry(String path) {
return null;
}
@Override
public Enumeration getEntryPaths(String path) {
return null;
}
@Override
public Dictionary getHeaders() {
return new Hashtable<>();
}
@Override
public Dictionary getHeaders(String locale) {
return getHeaders();
}
@Override
public long getLastModified() {
return 0;
}
@Override
public String getLocation() {
return ""; //$NON-NLS-1$
}
@Override
public ServiceReference>[] getRegisteredServices() {
return null;
}
@Override
public URL getResource(String name) {
return null;
}
/**
* @throws IOException
*/
@Override
public Enumeration getResources(String name) throws IOException {
return null;
}
@Override
public ServiceReference>[] getServicesInUse() {
return null;
}
@Override
public Map> getSignerCertificates(int signersType) {
return new HashMap<>(signers);
}
@Override
public int getState() {
return Bundle.UNINSTALLED;
}
@Override
public String getSymbolicName() {
return null;
}
@Override
public Version getVersion() {
return Version.emptyVersion;
}
@Override
public boolean hasPermission(Object permission) {
return false;
}
/**
* @throws ClassNotFoundException
*/
@Override
public Class> loadClass(String name) throws ClassNotFoundException {
throw new IllegalStateException();
}
/**
* @throws BundleException
*/
@Override
public void start(int options) throws BundleException {
throw new IllegalStateException();
}
/**
* @throws BundleException
*/
@Override
public void start() throws BundleException {
throw new IllegalStateException();
}
/**
* @throws BundleException
*/
@Override
public void stop(int options) throws BundleException {
throw new IllegalStateException();
}
/**
* @throws BundleException
*/
@Override
public void stop() throws BundleException {
throw new IllegalStateException();
}
/**
* @throws BundleException
*/
@Override
public void uninstall() throws BundleException {
throw new IllegalStateException();
}
/**
* @throws BundleException
*/
@Override
public void update() throws BundleException {
throw new IllegalStateException();
}
/**
* @throws BundleException
*/
@Override
public void update(InputStream in) throws BundleException {
throw new IllegalStateException();
}
@Override
public int compareTo(Bundle o) {
return 0;
}
@Override
public A adapt(Class type) {
throw new IllegalStateException();
}
@Override
public File getDataFile(String filename) {
return null;
}
}
private static class MockX509Certificate extends X509Certificate {
private final Principal subject;
private final Principal issuer;
MockX509Certificate(Principal subject, Principal issuer) {
this.subject = subject;
this.issuer = issuer;
}
@Override
public Principal getSubjectDN() {
return subject;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj instanceof MockX509Certificate)
return subject.equals(((MockX509Certificate) obj).subject)
&& issuer.equals(((MockX509Certificate) obj).issuer);
return false;
}
@Override
public int hashCode() {
return subject.hashCode() + issuer.hashCode();
}
@Override
public String toString() {
return subject.toString();
}
/**
* @throws CertificateExpiredException
* @throws java.security.cert.CertificateNotYetValidException
*/
@Override
public void checkValidity()
throws CertificateExpiredException, java.security.cert.CertificateNotYetValidException {
throw new UnsupportedOperationException();
}
/**
* @throws java.security.cert.CertificateExpiredException
* @throws java.security.cert.CertificateNotYetValidException
*/
@Override
public void checkValidity(Date var0) throws java.security.cert.CertificateExpiredException,
java.security.cert.CertificateNotYetValidException {
throw new UnsupportedOperationException();
}
@Override
public int getBasicConstraints() {
throw new UnsupportedOperationException();
}
@Override
public Principal getIssuerDN() {
return issuer;
}
@Override
public boolean[] getIssuerUniqueID() {
throw new UnsupportedOperationException();
}
@Override
public boolean[] getKeyUsage() {
throw new UnsupportedOperationException();
}
@Override
public Date getNotAfter() {
throw new UnsupportedOperationException();
}
@Override
public Date getNotBefore() {
throw new UnsupportedOperationException();
}
@Override
public BigInteger getSerialNumber() {
throw new UnsupportedOperationException();
}
@Override
public String getSigAlgName() {
throw new UnsupportedOperationException();
}
@Override
public String getSigAlgOID() {
throw new UnsupportedOperationException();
}
@Override
public byte[] getSigAlgParams() {
throw new UnsupportedOperationException();
}
@Override
public byte[] getSignature() {
throw new UnsupportedOperationException();
}
@Override
public boolean[] getSubjectUniqueID() {
throw new UnsupportedOperationException();
}
/**
* @throws CertificateEncodingException
*/
@Override
public byte[] getTBSCertificate() throws CertificateEncodingException {
throw new UnsupportedOperationException();
}
@Override
public int getVersion() {
throw new UnsupportedOperationException();
}
/**
* @throws CertificateEncodingException
*/
@Override
public byte[] getEncoded() throws CertificateEncodingException {
throw new UnsupportedOperationException();
}
@Override
public PublicKey getPublicKey() {
throw new UnsupportedOperationException();
}
/**
* @throws java.security.InvalidKeyException
* @throws java.security.NoSuchAlgorithmException
* @throws java.security.NoSuchProviderException
* @throws java.security.SignatureException
* @throws java.security.cert.CertificateException
*/
@Override
public void verify(PublicKey var0) throws java.security.InvalidKeyException,
java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException,
java.security.SignatureException, java.security.cert.CertificateException {
throw new UnsupportedOperationException();
}
/**
* @throws InvalidKeyException
* @throws NoSuchAlgorithmException
* @throws NoSuchProviderException
* @throws SignatureException
* @throws CertificateException
*/
@Override
public void verify(PublicKey var0, String var1) throws InvalidKeyException, NoSuchAlgorithmException,
NoSuchProviderException, SignatureException, CertificateException {
throw new UnsupportedOperationException();
}
@Override
public Set getCriticalExtensionOIDs() {
throw new UnsupportedOperationException();
}
@Override
public byte[] getExtensionValue(String var0) {
throw new UnsupportedOperationException();
}
@Override
public Set getNonCriticalExtensionOIDs() {
throw new UnsupportedOperationException();
}
@Override
public boolean hasUnsupportedCriticalExtension() {
throw new UnsupportedOperationException();
}
}
private static class MockPrincipal implements Principal {
private final String name;
MockPrincipal(String name) {
this.name = name;
}
@Override
public String getName() {
return name;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof MockPrincipal) {
return name.equals(((MockPrincipal) obj).name);
}
return false;
}
@Override
public int hashCode() {
return name.hashCode();
}
@Override
public String toString() {
return getName();
}
}
private static List parseDNchain(String dnChain) {
if (dnChain == null) {
throw new IllegalArgumentException("The DN chain must not be null."); //$NON-NLS-1$
}
List parsed = new ArrayList<>();
int startIndex = 0;
startIndex = skipSpaces(dnChain, startIndex);
while (startIndex < dnChain.length()) {
int endIndex = startIndex;
boolean inQuote = false;
out: while (endIndex < dnChain.length()) {
char c = dnChain.charAt(endIndex);
switch (c) {
case '"':
inQuote = !inQuote;
break;
case '\\':
endIndex++; // skip the escaped char
break;
case ';':
if (!inQuote)
break out;
}
endIndex++;
}
if (endIndex > dnChain.length()) {
throw new IllegalArgumentException("unterminated escape"); //$NON-NLS-1$
}
parsed.add(dnChain.substring(startIndex, endIndex));
startIndex = endIndex + 1;
startIndex = skipSpaces(dnChain, startIndex);
}
return parsed;
}
private static int skipSpaces(String dnChain, int startIndex) {
while (startIndex < dnChain.length() && dnChain.charAt(startIndex) == ' ') {
startIndex++;
}
return startIndex;
}
}