8187443: Forest Consolidation: Move files to unified layout

Reviewed-by: darcy, ihse
This commit is contained in:
Erik Joelsson 2017-09-12 19:03:39 +02:00
parent 270fe13182
commit 3789983e89
56923 changed files with 3 additions and 15727 deletions

View file

@ -0,0 +1,955 @@
/*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
import java.util.ArrayList;
import java.util.List;
import sun.security.util.Debug;
import sun.security.util.FilePermCompat;
import sun.security.util.SecurityConstants;
/**
* An AccessControlContext is used to make system resource access decisions
* based on the context it encapsulates.
*
* <p>More specifically, it encapsulates a context and
* has a single method, {@code checkPermission},
* that is equivalent to the {@code checkPermission} method
* in the AccessController class, with one difference: The AccessControlContext
* {@code checkPermission} method makes access decisions based on the
* context it encapsulates,
* rather than that of the current execution thread.
*
* <p>Thus, the purpose of AccessControlContext is for those situations where
* a security check that should be made within a given context
* actually needs to be done from within a
* <i>different</i> context (for example, from within a worker thread).
*
* <p> An AccessControlContext is created by calling the
* {@code AccessController.getContext} method.
* The {@code getContext} method takes a "snapshot"
* of the current calling context, and places
* it in an AccessControlContext object, which it returns. A sample call is
* the following:
*
* <pre>
* AccessControlContext acc = AccessController.getContext()
* </pre>
*
* <p>
* Code within a different context can subsequently call the
* {@code checkPermission} method on the
* previously-saved AccessControlContext object. A sample call is the
* following:
*
* <pre>
* acc.checkPermission(permission)
* </pre>
*
* @see AccessController
*
* @author Roland Schemers
* @since 1.2
*/
public final class AccessControlContext {
private ProtectionDomain[] context;
// isPrivileged and isAuthorized are referenced by the VM - do not remove
// or change their names
private boolean isPrivileged;
private boolean isAuthorized = false;
// Note: This field is directly used by the virtual machine
// native codes. Don't touch it.
private AccessControlContext privilegedContext;
private DomainCombiner combiner = null;
// limited privilege scope
private Permission[] permissions;
private AccessControlContext parent;
private boolean isWrapped;
// is constrained by limited privilege scope?
private boolean isLimited;
private ProtectionDomain[] limitedContext;
private static boolean debugInit = false;
private static Debug debug = null;
static Debug getDebug()
{
if (debugInit)
return debug;
else {
if (Policy.isSet()) {
debug = Debug.getInstance("access");
debugInit = true;
}
return debug;
}
}
/**
* Create an AccessControlContext with the given array of ProtectionDomains.
* Context must not be null. Duplicate domains will be removed from the
* context.
*
* @param context the ProtectionDomains associated with this context.
* The non-duplicate domains are copied from the array. Subsequent
* changes to the array will not affect this AccessControlContext.
* @throws NullPointerException if {@code context} is {@code null}
*/
public AccessControlContext(ProtectionDomain[] context)
{
if (context.length == 0) {
this.context = null;
} else if (context.length == 1) {
if (context[0] != null) {
this.context = context.clone();
} else {
this.context = null;
}
} else {
List<ProtectionDomain> v = new ArrayList<>(context.length);
for (int i =0; i< context.length; i++) {
if ((context[i] != null) && (!v.contains(context[i])))
v.add(context[i]);
}
if (!v.isEmpty()) {
this.context = new ProtectionDomain[v.size()];
this.context = v.toArray(this.context);
}
}
}
/**
* Create a new {@code AccessControlContext} with the given
* {@code AccessControlContext} and {@code DomainCombiner}.
* This constructor associates the provided
* {@code DomainCombiner} with the provided
* {@code AccessControlContext}.
*
* @param acc the {@code AccessControlContext} associated
* with the provided {@code DomainCombiner}.
*
* @param combiner the {@code DomainCombiner} to be associated
* with the provided {@code AccessControlContext}.
*
* @exception NullPointerException if the provided
* {@code context} is {@code null}.
*
* @exception SecurityException if a security manager is installed and the
* caller does not have the "createAccessControlContext"
* {@link SecurityPermission}
* @since 1.3
*/
public AccessControlContext(AccessControlContext acc,
DomainCombiner combiner) {
this(acc, combiner, false);
}
/**
* package private to allow calls from ProtectionDomain without performing
* the security check for {@linkplain SecurityConstants#CREATE_ACC_PERMISSION}
* permission
*/
AccessControlContext(AccessControlContext acc,
DomainCombiner combiner,
boolean preauthorized) {
if (!preauthorized) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(SecurityConstants.CREATE_ACC_PERMISSION);
this.isAuthorized = true;
}
} else {
this.isAuthorized = true;
}
this.context = acc.context;
// we do not need to run the combine method on the
// provided ACC. it was already "combined" when the
// context was originally retrieved.
//
// at this point in time, we simply throw away the old
// combiner and use the newly provided one.
this.combiner = combiner;
}
/**
* package private for AccessController
*
* This "argument wrapper" context will be passed as the actual context
* parameter on an internal doPrivileged() call used in the implementation.
*/
AccessControlContext(ProtectionDomain caller, DomainCombiner combiner,
AccessControlContext parent, AccessControlContext context,
Permission[] perms)
{
/*
* Combine the domains from the doPrivileged() context into our
* wrapper context, if necessary.
*/
ProtectionDomain[] callerPDs = null;
if (caller != null) {
callerPDs = new ProtectionDomain[] { caller };
}
if (context != null) {
if (combiner != null) {
this.context = combiner.combine(callerPDs, context.context);
} else {
this.context = combine(callerPDs, context.context);
}
} else {
/*
* Call combiner even if there is seemingly nothing to combine.
*/
if (combiner != null) {
this.context = combiner.combine(callerPDs, null);
} else {
this.context = combine(callerPDs, null);
}
}
this.combiner = combiner;
Permission[] tmp = null;
if (perms != null) {
tmp = new Permission[perms.length];
for (int i=0; i < perms.length; i++) {
if (perms[i] == null) {
throw new NullPointerException("permission can't be null");
}
/*
* An AllPermission argument is equivalent to calling
* doPrivileged() without any limit permissions.
*/
if (perms[i].getClass() == AllPermission.class) {
parent = null;
}
// Add altPath into permission for compatibility.
tmp[i] = FilePermCompat.newPermPlusAltPath(perms[i]);
}
}
/*
* For a doPrivileged() with limited privilege scope, initialize
* the relevant fields.
*
* The limitedContext field contains the union of all domains which
* are enclosed by this limited privilege scope. In other words,
* it contains all of the domains which could potentially be checked
* if none of the limiting permissions implied a requested permission.
*/
if (parent != null) {
this.limitedContext = combine(parent.context, parent.limitedContext);
this.isLimited = true;
this.isWrapped = true;
this.permissions = tmp;
this.parent = parent;
this.privilegedContext = context; // used in checkPermission2()
}
this.isAuthorized = true;
}
/**
* package private constructor for AccessController.getContext()
*/
AccessControlContext(ProtectionDomain[] context,
boolean isPrivileged)
{
this.context = context;
this.isPrivileged = isPrivileged;
this.isAuthorized = true;
}
/**
* Constructor for JavaSecurityAccess.doIntersectionPrivilege()
*/
AccessControlContext(ProtectionDomain[] context,
AccessControlContext privilegedContext)
{
this.context = context;
this.privilegedContext = privilegedContext;
this.isPrivileged = true;
}
/**
* Returns this context's context.
*/
ProtectionDomain[] getContext() {
return context;
}
/**
* Returns true if this context is privileged.
*/
boolean isPrivileged()
{
return isPrivileged;
}
/**
* get the assigned combiner from the privileged or inherited context
*/
DomainCombiner getAssignedCombiner() {
AccessControlContext acc;
if (isPrivileged) {
acc = privilegedContext;
} else {
acc = AccessController.getInheritedAccessControlContext();
}
if (acc != null) {
return acc.combiner;
}
return null;
}
/**
* Get the {@code DomainCombiner} associated with this
* {@code AccessControlContext}.
*
* @return the {@code DomainCombiner} associated with this
* {@code AccessControlContext}, or {@code null}
* if there is none.
*
* @exception SecurityException if a security manager is installed and
* the caller does not have the "getDomainCombiner"
* {@link SecurityPermission}
* @since 1.3
*/
public DomainCombiner getDomainCombiner() {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(SecurityConstants.GET_COMBINER_PERMISSION);
}
return getCombiner();
}
/**
* package private for AccessController
*/
DomainCombiner getCombiner() {
return combiner;
}
boolean isAuthorized() {
return isAuthorized;
}
/**
* Determines whether the access request indicated by the
* specified permission should be allowed or denied, based on
* the security policy currently in effect, and the context in
* this object. The request is allowed only if every ProtectionDomain
* in the context implies the permission. Otherwise the request is
* denied.
*
* <p>
* This method quietly returns if the access request
* is permitted, or throws a suitable AccessControlException otherwise.
*
* @param perm the requested permission.
*
* @exception AccessControlException if the specified permission
* is not permitted, based on the current security policy and the
* context encapsulated by this object.
* @exception NullPointerException if the permission to check for is null.
*/
public void checkPermission(Permission perm)
throws AccessControlException
{
boolean dumpDebug = false;
if (perm == null) {
throw new NullPointerException("permission can't be null");
}
if (getDebug() != null) {
// If "codebase" is not specified, we dump the info by default.
dumpDebug = !Debug.isOn("codebase=");
if (!dumpDebug) {
// If "codebase" is specified, only dump if the specified code
// value is in the stack.
for (int i = 0; context != null && i < context.length; i++) {
if (context[i].getCodeSource() != null &&
context[i].getCodeSource().getLocation() != null &&
Debug.isOn("codebase=" + context[i].getCodeSource().getLocation().toString())) {
dumpDebug = true;
break;
}
}
}
dumpDebug &= !Debug.isOn("permission=") ||
Debug.isOn("permission=" + perm.getClass().getCanonicalName());
if (dumpDebug && Debug.isOn("stack")) {
Thread.dumpStack();
}
if (dumpDebug && Debug.isOn("domain")) {
if (context == null) {
debug.println("domain (context is null)");
} else {
for (int i=0; i< context.length; i++) {
debug.println("domain "+i+" "+context[i]);
}
}
}
}
/*
* iterate through the ProtectionDomains in the context.
* Stop at the first one that doesn't allow the
* requested permission (throwing an exception).
*
*/
/* if ctxt is null, all we had on the stack were system domains,
or the first domain was a Privileged system domain. This
is to make the common case for system code very fast */
if (context == null) {
checkPermission2(perm);
return;
}
for (int i=0; i< context.length; i++) {
if (context[i] != null && !context[i].impliesWithAltFilePerm(perm)) {
if (dumpDebug) {
debug.println("access denied " + perm);
}
if (Debug.isOn("failure") && debug != null) {
// Want to make sure this is always displayed for failure,
// but do not want to display again if already displayed
// above.
if (!dumpDebug) {
debug.println("access denied " + perm);
}
Thread.dumpStack();
final ProtectionDomain pd = context[i];
final Debug db = debug;
AccessController.doPrivileged (new PrivilegedAction<>() {
public Void run() {
db.println("domain that failed "+pd);
return null;
}
});
}
throw new AccessControlException("access denied "+perm, perm);
}
}
// allow if all of them allowed access
if (dumpDebug) {
debug.println("access allowed "+perm);
}
checkPermission2(perm);
}
/*
* Check the domains associated with the limited privilege scope.
*/
private void checkPermission2(Permission perm) {
if (!isLimited) {
return;
}
/*
* Check the doPrivileged() context parameter, if present.
*/
if (privilegedContext != null) {
privilegedContext.checkPermission2(perm);
}
/*
* Ignore the limited permissions and parent fields of a wrapper
* context since they were already carried down into the unwrapped
* context.
*/
if (isWrapped) {
return;
}
/*
* Try to match any limited privilege scope.
*/
if (permissions != null) {
Class<?> permClass = perm.getClass();
for (int i=0; i < permissions.length; i++) {
Permission limit = permissions[i];
if (limit.getClass().equals(permClass) && limit.implies(perm)) {
return;
}
}
}
/*
* Check the limited privilege scope up the call stack or the inherited
* parent thread call stack of this ACC.
*/
if (parent != null) {
/*
* As an optimization, if the parent context is the inherited call
* stack context from a parent thread then checking the protection
* domains of the parent context is redundant since they have
* already been merged into the child thread's context by
* optimize(). When parent is set to an inherited context this
* context was not directly created by a limited scope
* doPrivileged() and it does not have its own limited permissions.
*/
if (permissions == null) {
parent.checkPermission2(perm);
} else {
parent.checkPermission(perm);
}
}
}
/**
* Take the stack-based context (this) and combine it with the
* privileged or inherited context, if need be. Any limited
* privilege scope is flagged regardless of whether the assigned
* context comes from an immediately enclosing limited doPrivileged().
* The limited privilege scope can indirectly flow from the inherited
* parent thread or an assigned context previously captured by getContext().
*/
AccessControlContext optimize() {
// the assigned (privileged or inherited) context
AccessControlContext acc;
DomainCombiner combiner = null;
AccessControlContext parent = null;
Permission[] permissions = null;
if (isPrivileged) {
acc = privilegedContext;
if (acc != null) {
/*
* If the context is from a limited scope doPrivileged() then
* copy the permissions and parent fields out of the wrapper
* context that was created to hold them.
*/
if (acc.isWrapped) {
permissions = acc.permissions;
parent = acc.parent;
}
}
} else {
acc = AccessController.getInheritedAccessControlContext();
if (acc != null) {
/*
* If the inherited context is constrained by a limited scope
* doPrivileged() then set it as our parent so we will process
* the non-domain-related state.
*/
if (acc.isLimited) {
parent = acc;
}
}
}
// this.context could be null if only system code is on the stack;
// in that case, ignore the stack context
boolean skipStack = (context == null);
// acc.context could be null if only system code was involved;
// in that case, ignore the assigned context
boolean skipAssigned = (acc == null || acc.context == null);
ProtectionDomain[] assigned = (skipAssigned) ? null : acc.context;
ProtectionDomain[] pd;
// if there is no enclosing limited privilege scope on the stack or
// inherited from a parent thread
boolean skipLimited = ((acc == null || !acc.isWrapped) && parent == null);
if (acc != null && acc.combiner != null) {
// let the assigned acc's combiner do its thing
if (getDebug() != null) {
debug.println("AccessControlContext invoking the Combiner");
}
// No need to clone current and assigned.context
// combine() will not update them
combiner = acc.combiner;
pd = combiner.combine(context, assigned);
} else {
if (skipStack) {
if (skipAssigned) {
calculateFields(acc, parent, permissions);
return this;
} else if (skipLimited) {
return acc;
}
} else if (assigned != null) {
if (skipLimited) {
// optimization: if there is a single stack domain and
// that domain is already in the assigned context; no
// need to combine
if (context.length == 1 && context[0] == assigned[0]) {
return acc;
}
}
}
pd = combine(context, assigned);
if (skipLimited && !skipAssigned && pd == assigned) {
return acc;
} else if (skipAssigned && pd == context) {
calculateFields(acc, parent, permissions);
return this;
}
}
// Reuse existing ACC
this.context = pd;
this.combiner = combiner;
this.isPrivileged = false;
calculateFields(acc, parent, permissions);
return this;
}
/*
* Combine the current (stack) and assigned domains.
*/
private static ProtectionDomain[] combine(ProtectionDomain[] current,
ProtectionDomain[] assigned) {
// current could be null if only system code is on the stack;
// in that case, ignore the stack context
boolean skipStack = (current == null);
// assigned could be null if only system code was involved;
// in that case, ignore the assigned context
boolean skipAssigned = (assigned == null);
int slen = (skipStack) ? 0 : current.length;
// optimization: if there is no assigned context and the stack length
// is less then or equal to two; there is no reason to compress the
// stack context, it already is
if (skipAssigned && slen <= 2) {
return current;
}
int n = (skipAssigned) ? 0 : assigned.length;
// now we combine both of them, and create a new context
ProtectionDomain[] pd = new ProtectionDomain[slen + n];
// first copy in the assigned context domains, no need to compress
if (!skipAssigned) {
System.arraycopy(assigned, 0, pd, 0, n);
}
// now add the stack context domains, discarding nulls and duplicates
outer:
for (int i = 0; i < slen; i++) {
ProtectionDomain sd = current[i];
if (sd != null) {
for (int j = 0; j < n; j++) {
if (sd == pd[j]) {
continue outer;
}
}
pd[n++] = sd;
}
}
// if length isn't equal, we need to shorten the array
if (n != pd.length) {
// optimization: if we didn't really combine anything
if (!skipAssigned && n == assigned.length) {
return assigned;
} else if (skipAssigned && n == slen) {
return current;
}
ProtectionDomain[] tmp = new ProtectionDomain[n];
System.arraycopy(pd, 0, tmp, 0, n);
pd = tmp;
}
return pd;
}
/*
* Calculate the additional domains that could potentially be reached via
* limited privilege scope. Mark the context as being subject to limited
* privilege scope unless the reachable domains (if any) are already
* contained in this domain context (in which case any limited
* privilege scope checking would be redundant).
*/
private void calculateFields(AccessControlContext assigned,
AccessControlContext parent, Permission[] permissions)
{
ProtectionDomain[] parentLimit = null;
ProtectionDomain[] assignedLimit = null;
ProtectionDomain[] newLimit;
parentLimit = (parent != null)? parent.limitedContext: null;
assignedLimit = (assigned != null)? assigned.limitedContext: null;
newLimit = combine(parentLimit, assignedLimit);
if (newLimit != null) {
if (context == null || !containsAllPDs(newLimit, context)) {
this.limitedContext = newLimit;
this.permissions = permissions;
this.parent = parent;
this.isLimited = true;
}
}
}
/**
* Checks two AccessControlContext objects for equality.
* Checks that {@code obj} is
* an AccessControlContext and has the same set of ProtectionDomains
* as this context.
*
* @param obj the object we are testing for equality with this object.
* @return true if {@code obj} is an AccessControlContext, and has the
* same set of ProtectionDomains as this context, false otherwise.
*/
public boolean equals(Object obj) {
if (obj == this)
return true;
if (! (obj instanceof AccessControlContext))
return false;
AccessControlContext that = (AccessControlContext) obj;
if (!equalContext(that))
return false;
if (!equalLimitedContext(that))
return false;
return true;
}
/*
* Compare for equality based on state that is free of limited
* privilege complications.
*/
private boolean equalContext(AccessControlContext that) {
if (!equalPDs(this.context, that.context))
return false;
if (this.combiner == null && that.combiner != null)
return false;
if (this.combiner != null && !this.combiner.equals(that.combiner))
return false;
return true;
}
private boolean equalPDs(ProtectionDomain[] a, ProtectionDomain[] b) {
if (a == null) {
return (b == null);
}
if (b == null)
return false;
if (!(containsAllPDs(a, b) && containsAllPDs(b, a)))
return false;
return true;
}
/*
* Compare for equality based on state that is captured during a
* call to AccessController.getContext() when a limited privilege
* scope is in effect.
*/
private boolean equalLimitedContext(AccessControlContext that) {
if (that == null)
return false;
/*
* If neither instance has limited privilege scope then we're done.
*/
if (!this.isLimited && !that.isLimited)
return true;
/*
* If only one instance has limited privilege scope then we're done.
*/
if (!(this.isLimited && that.isLimited))
return false;
/*
* Wrapped instances should never escape outside the implementation
* this class and AccessController so this will probably never happen
* but it only makes any sense to compare if they both have the same
* isWrapped state.
*/
if ((this.isWrapped && !that.isWrapped) ||
(!this.isWrapped && that.isWrapped)) {
return false;
}
if (this.permissions == null && that.permissions != null)
return false;
if (this.permissions != null && that.permissions == null)
return false;
if (!(this.containsAllLimits(that) && that.containsAllLimits(this)))
return false;
/*
* Skip through any wrapped contexts.
*/
AccessControlContext thisNextPC = getNextPC(this);
AccessControlContext thatNextPC = getNextPC(that);
/*
* The protection domains and combiner of a privilegedContext are
* not relevant because they have already been included in the context
* of this instance by optimize() so we only care about any limited
* privilege state they may have.
*/
if (thisNextPC == null && thatNextPC != null && thatNextPC.isLimited)
return false;
if (thisNextPC != null && !thisNextPC.equalLimitedContext(thatNextPC))
return false;
if (this.parent == null && that.parent != null)
return false;
if (this.parent != null && !this.parent.equals(that.parent))
return false;
return true;
}
/*
* Follow the privilegedContext link making our best effort to skip
* through any wrapper contexts.
*/
private static AccessControlContext getNextPC(AccessControlContext acc) {
while (acc != null && acc.privilegedContext != null) {
acc = acc.privilegedContext;
if (!acc.isWrapped)
return acc;
}
return null;
}
private static boolean containsAllPDs(ProtectionDomain[] thisContext,
ProtectionDomain[] thatContext) {
boolean match = false;
//
// ProtectionDomains within an ACC currently cannot be null
// and this is enforced by the constructor and the various
// optimize methods. However, historically this logic made attempts
// to support the notion of a null PD and therefore this logic continues
// to support that notion.
ProtectionDomain thisPd;
for (int i = 0; i < thisContext.length; i++) {
match = false;
if ((thisPd = thisContext[i]) == null) {
for (int j = 0; (j < thatContext.length) && !match; j++) {
match = (thatContext[j] == null);
}
} else {
Class<?> thisPdClass = thisPd.getClass();
ProtectionDomain thatPd;
for (int j = 0; (j < thatContext.length) && !match; j++) {
thatPd = thatContext[j];
// Class check required to avoid PD exposure (4285406)
match = (thatPd != null &&
thisPdClass == thatPd.getClass() && thisPd.equals(thatPd));
}
}
if (!match) return false;
}
return match;
}
private boolean containsAllLimits(AccessControlContext that) {
boolean match = false;
Permission thisPerm;
if (this.permissions == null && that.permissions == null)
return true;
for (int i = 0; i < this.permissions.length; i++) {
Permission limit = this.permissions[i];
Class <?> limitClass = limit.getClass();
match = false;
for (int j = 0; (j < that.permissions.length) && !match; j++) {
Permission perm = that.permissions[j];
match = (limitClass.equals(perm.getClass()) &&
limit.equals(perm));
}
if (!match) return false;
}
return match;
}
/**
* Returns the hash code value for this context. The hash code
* is computed by exclusive or-ing the hash code of all the protection
* domains in the context together.
*
* @return a hash code value for this context.
*/
public int hashCode() {
int hashCode = 0;
if (context == null)
return hashCode;
for (int i =0; i < context.length; i++) {
if (context[i] != null)
hashCode ^= context[i].hashCode();
}
return hashCode;
}
}

View file

@ -0,0 +1,83 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
/**
* <p> This exception is thrown by the AccessController to indicate
* that a requested access (to a critical system resource such as the
* file system or the network) is denied.
*
* <p> The reason to deny access can vary. For example, the requested
* permission might be of an incorrect type, contain an invalid
* value, or request access that is not allowed according to the
* security policy. Such information should be given whenever
* possible at the time the exception is thrown.
*
* @author Li Gong
* @author Roland Schemers
* @since 1.2
*/
public class AccessControlException extends SecurityException {
private static final long serialVersionUID = 5138225684096988535L;
// the permission that caused the exception to be thrown.
private Permission perm;
/**
* Constructs an {@code AccessControlException} with the
* specified, detailed message.
*
* @param s the detail message.
*/
public AccessControlException(String s) {
super(s);
}
/**
* Constructs an {@code AccessControlException} with the
* specified, detailed message, and the requested permission that caused
* the exception.
*
* @param s the detail message.
* @param p the permission that caused the exception.
*/
public AccessControlException(String s, Permission p) {
super(s);
perm = p;
}
/**
* Gets the Permission object associated with this exception, or
* null if there was no corresponding Permission object.
*
* @return the Permission object.
*/
public Permission getPermission() {
return perm;
}
}

View file

@ -0,0 +1,897 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
import sun.security.util.Debug;
import jdk.internal.reflect.CallerSensitive;
import jdk.internal.reflect.Reflection;
/**
* <p> The AccessController class is used for access control operations
* and decisions.
*
* <p> More specifically, the AccessController class is used for
* three purposes:
*
* <ul>
* <li> to decide whether an access to a critical system
* resource is to be allowed or denied, based on the security policy
* currently in effect,
* <li>to mark code as being "privileged", thus affecting subsequent
* access determinations, and
* <li>to obtain a "snapshot" of the current calling context so
* access-control decisions from a different context can be made with
* respect to the saved context. </ul>
*
* <p> The {@link #checkPermission(Permission) checkPermission} method
* determines whether the access request indicated by a specified
* permission should be granted or denied. A sample call appears
* below. In this example, {@code checkPermission} will determine
* whether or not to grant "read" access to the file named "testFile" in
* the "/temp" directory.
*
* <pre>
*
* FilePermission perm = new FilePermission("/temp/testFile", "read");
* AccessController.checkPermission(perm);
*
* </pre>
*
* <p> If a requested access is allowed,
* {@code checkPermission} returns quietly. If denied, an
* AccessControlException is
* thrown. AccessControlException can also be thrown if the requested
* permission is of an incorrect type or contains an invalid value.
* Such information is given whenever possible.
*
* Suppose the current thread traversed m callers, in the order of caller 1
* to caller 2 to caller m. Then caller m invoked the
* {@code checkPermission} method.
* The {@code checkPermission} method determines whether access
* is granted or denied based on the following algorithm:
*
* <pre> {@code
* for (int i = m; i > 0; i--) {
*
* if (caller i's domain does not have the permission)
* throw AccessControlException
*
* else if (caller i is marked as privileged) {
* if (a context was specified in the call to doPrivileged)
* context.checkPermission(permission)
* if (limited permissions were specified in the call to doPrivileged) {
* for (each limited permission) {
* if (the limited permission implies the requested permission)
* return;
* }
* } else
* return;
* }
* }
*
* // Next, check the context inherited when the thread was created.
* // Whenever a new thread is created, the AccessControlContext at
* // that time is stored and associated with the new thread, as the
* // "inherited" context.
*
* inheritedContext.checkPermission(permission);
* }</pre>
*
* <p> A caller can be marked as being "privileged"
* (see {@link #doPrivileged(PrivilegedAction) doPrivileged} and below).
* When making access control decisions, the {@code checkPermission}
* method stops checking if it reaches a caller that
* was marked as "privileged" via a {@code doPrivileged}
* call without a context argument (see below for information about a
* context argument). If that caller's domain has the
* specified permission and at least one limiting permission argument (if any)
* implies the requested permission, no further checking is done and
* {@code checkPermission}
* returns quietly, indicating that the requested access is allowed.
* If that domain does not have the specified permission, an exception
* is thrown, as usual. If the caller's domain had the specified permission
* but it was not implied by any limiting permission arguments given in the call
* to {@code doPrivileged} then the permission checking continues
* until there are no more callers or another {@code doPrivileged}
* call matches the requested permission and returns normally.
*
* <p> The normal use of the "privileged" feature is as follows. If you
* don't need to return a value from within the "privileged" block, do
* the following:
*
* <pre> {@code
* somemethod() {
* ...normal code here...
* AccessController.doPrivileged(new PrivilegedAction<Void>() {
* public Void run() {
* // privileged code goes here, for example:
* System.loadLibrary("awt");
* return null; // nothing to return
* }
* });
* ...normal code here...
* }}</pre>
*
* <p>
* PrivilegedAction is an interface with a single method, named
* {@code run}.
* The above example shows creation of an implementation
* of that interface; a concrete implementation of the
* {@code run} method is supplied.
* When the call to {@code doPrivileged} is made, an
* instance of the PrivilegedAction implementation is passed
* to it. The {@code doPrivileged} method calls the
* {@code run} method from the PrivilegedAction
* implementation after enabling privileges, and returns the
* {@code run} method's return value as the
* {@code doPrivileged} return value (which is
* ignored in this example).
*
* <p> If you need to return a value, you can do something like the following:
*
* <pre> {@code
* somemethod() {
* ...normal code here...
* String user = AccessController.doPrivileged(
* new PrivilegedAction<String>() {
* public String run() {
* return System.getProperty("user.name");
* }
* });
* ...normal code here...
* }}</pre>
*
* <p>If the action performed in your {@code run} method could
* throw a "checked" exception (those listed in the {@code throws} clause
* of a method), then you need to use the
* {@code PrivilegedExceptionAction} interface instead of the
* {@code PrivilegedAction} interface:
*
* <pre> {@code
* somemethod() throws FileNotFoundException {
* ...normal code here...
* try {
* FileInputStream fis = AccessController.doPrivileged(
* new PrivilegedExceptionAction<FileInputStream>() {
* public FileInputStream run() throws FileNotFoundException {
* return new FileInputStream("someFile");
* }
* });
* } catch (PrivilegedActionException e) {
* // e.getException() should be an instance of FileNotFoundException,
* // as only "checked" exceptions will be "wrapped" in a
* // PrivilegedActionException.
* throw (FileNotFoundException) e.getException();
* }
* ...normal code here...
* }}</pre>
*
* <p> Be *very* careful in your use of the "privileged" construct, and
* always remember to make the privileged code section as small as possible.
* You can pass {@code Permission} arguments to further limit the
* scope of the "privilege" (see below).
*
*
* <p> Note that {@code checkPermission} always performs security checks
* within the context of the currently executing thread.
* Sometimes a security check that should be made within a given context
* will actually need to be done from within a
* <i>different</i> context (for example, from within a worker thread).
* The {@link #getContext() getContext} method and
* AccessControlContext class are provided
* for this situation. The {@code getContext} method takes a "snapshot"
* of the current calling context, and places
* it in an AccessControlContext object, which it returns. A sample call is
* the following:
*
* <pre>
*
* AccessControlContext acc = AccessController.getContext()
*
* </pre>
*
* <p>
* AccessControlContext itself has a {@code checkPermission} method
* that makes access decisions based on the context <i>it</i> encapsulates,
* rather than that of the current execution thread.
* Code within a different context can thus call that method on the
* previously-saved AccessControlContext object. A sample call is the
* following:
*
* <pre>
*
* acc.checkPermission(permission)
*
* </pre>
*
* <p> There are also times where you don't know a priori which permissions
* to check the context against. In these cases you can use the
* doPrivileged method that takes a context. You can also limit the scope
* of the privileged code by passing additional {@code Permission}
* parameters.
*
* <pre> {@code
* somemethod() {
* AccessController.doPrivileged(new PrivilegedAction<Object>() {
* public Object run() {
* // Code goes here. Any permission checks within this
* // run method will require that the intersection of the
* // caller's protection domain and the snapshot's
* // context have the desired permission. If a requested
* // permission is not implied by the limiting FilePermission
* // argument then checking of the thread continues beyond the
* // caller of doPrivileged.
* }
* }, acc, new FilePermission("/temp/*", read));
* ...normal code here...
* }}</pre>
* <p> Passing a limiting {@code Permission} argument of an instance of
* {@code AllPermission} is equivalent to calling the equivalent
* {@code doPrivileged} method without limiting {@code Permission}
* arguments. Passing a zero length array of {@code Permission} disables
* the code privileges so that checking always continues beyond the caller of
* that {@code doPrivileged} method.
*
* @see AccessControlContext
*
* @author Li Gong
* @author Roland Schemers
* @since 1.2
*/
public final class AccessController {
/**
* Don't allow anyone to instantiate an AccessController
*/
private AccessController() { }
/**
* Performs the specified {@code PrivilegedAction} with privileges
* enabled. The action is performed with <i>all</i> of the permissions
* possessed by the caller's protection domain.
*
* <p> If the action's {@code run} method throws an (unchecked)
* exception, it will propagate through this method.
*
* <p> Note that any DomainCombiner associated with the current
* AccessControlContext will be ignored while the action is performed.
*
* @param <T> the type of the value returned by the PrivilegedAction's
* {@code run} method.
*
* @param action the action to be performed.
*
* @return the value returned by the action's {@code run} method.
*
* @exception NullPointerException if the action is {@code null}
*
* @see #doPrivileged(PrivilegedAction,AccessControlContext)
* @see #doPrivileged(PrivilegedExceptionAction)
* @see #doPrivilegedWithCombiner(PrivilegedAction)
* @see java.security.DomainCombiner
*/
@CallerSensitive
public static native <T> T doPrivileged(PrivilegedAction<T> action);
/**
* Performs the specified {@code PrivilegedAction} with privileges
* enabled. The action is performed with <i>all</i> of the permissions
* possessed by the caller's protection domain.
*
* <p> If the action's {@code run} method throws an (unchecked)
* exception, it will propagate through this method.
*
* <p> This method preserves the current AccessControlContext's
* DomainCombiner (which may be null) while the action is performed.
*
* @param <T> the type of the value returned by the PrivilegedAction's
* {@code run} method.
*
* @param action the action to be performed.
*
* @return the value returned by the action's {@code run} method.
*
* @exception NullPointerException if the action is {@code null}
*
* @see #doPrivileged(PrivilegedAction)
* @see java.security.DomainCombiner
*
* @since 1.6
*/
@CallerSensitive
public static <T> T doPrivilegedWithCombiner(PrivilegedAction<T> action) {
AccessControlContext acc = getStackAccessControlContext();
if (acc == null) {
return AccessController.doPrivileged(action);
}
DomainCombiner dc = acc.getAssignedCombiner();
return AccessController.doPrivileged(action,
preserveCombiner(dc, Reflection.getCallerClass()));
}
/**
* Performs the specified {@code PrivilegedAction} with privileges
* enabled and restricted by the specified {@code AccessControlContext}.
* The action is performed with the intersection of the permissions
* possessed by the caller's protection domain, and those possessed
* by the domains represented by the specified {@code AccessControlContext}.
* <p>
* If the action's {@code run} method throws an (unchecked) exception,
* it will propagate through this method.
* <p>
* If a security manager is installed and the specified
* {@code AccessControlContext} was not created by system code and the
* caller's {@code ProtectionDomain} has not been granted the
* {@literal "createAccessControlContext"}
* {@link java.security.SecurityPermission}, then the action is performed
* with no permissions.
*
* @param <T> the type of the value returned by the PrivilegedAction's
* {@code run} method.
* @param action the action to be performed.
* @param context an <i>access control context</i>
* representing the restriction to be applied to the
* caller's domain's privileges before performing
* the specified action. If the context is
* {@code null}, then no additional restriction is applied.
*
* @return the value returned by the action's {@code run} method.
*
* @exception NullPointerException if the action is {@code null}
*
* @see #doPrivileged(PrivilegedAction)
* @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
*/
@CallerSensitive
public static native <T> T doPrivileged(PrivilegedAction<T> action,
AccessControlContext context);
/**
* Performs the specified {@code PrivilegedAction} with privileges
* enabled and restricted by the specified
* {@code AccessControlContext} and with a privilege scope limited
* by specified {@code Permission} arguments.
*
* The action is performed with the intersection of the permissions
* possessed by the caller's protection domain, and those possessed
* by the domains represented by the specified
* {@code AccessControlContext}.
* <p>
* If the action's {@code run} method throws an (unchecked) exception,
* it will propagate through this method.
* <p>
* If a security manager is installed and the specified
* {@code AccessControlContext} was not created by system code and the
* caller's {@code ProtectionDomain} has not been granted the
* {@literal "createAccessControlContext"}
* {@link java.security.SecurityPermission}, then the action is performed
* with no permissions.
*
* @param <T> the type of the value returned by the PrivilegedAction's
* {@code run} method.
* @param action the action to be performed.
* @param context an <i>access control context</i>
* representing the restriction to be applied to the
* caller's domain's privileges before performing
* the specified action. If the context is
* {@code null},
* then no additional restriction is applied.
* @param perms the {@code Permission} arguments which limit the
* scope of the caller's privileges. The number of arguments
* is variable.
*
* @return the value returned by the action's {@code run} method.
*
* @throws NullPointerException if action or perms or any element of
* perms is {@code null}
*
* @see #doPrivileged(PrivilegedAction)
* @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
*
* @since 1.8
*/
@CallerSensitive
public static <T> T doPrivileged(PrivilegedAction<T> action,
AccessControlContext context, Permission... perms) {
AccessControlContext parent = getContext();
if (perms == null) {
throw new NullPointerException("null permissions parameter");
}
Class <?> caller = Reflection.getCallerClass();
return AccessController.doPrivileged(action, createWrapper(null,
caller, parent, context, perms));
}
/**
* Performs the specified {@code PrivilegedAction} with privileges
* enabled and restricted by the specified
* {@code AccessControlContext} and with a privilege scope limited
* by specified {@code Permission} arguments.
*
* The action is performed with the intersection of the permissions
* possessed by the caller's protection domain, and those possessed
* by the domains represented by the specified
* {@code AccessControlContext}.
* <p>
* If the action's {@code run} method throws an (unchecked) exception,
* it will propagate through this method.
*
* <p> This method preserves the current AccessControlContext's
* DomainCombiner (which may be null) while the action is performed.
* <p>
* If a security manager is installed and the specified
* {@code AccessControlContext} was not created by system code and the
* caller's {@code ProtectionDomain} has not been granted the
* {@literal "createAccessControlContext"}
* {@link java.security.SecurityPermission}, then the action is performed
* with no permissions.
*
* @param <T> the type of the value returned by the PrivilegedAction's
* {@code run} method.
* @param action the action to be performed.
* @param context an <i>access control context</i>
* representing the restriction to be applied to the
* caller's domain's privileges before performing
* the specified action. If the context is
* {@code null},
* then no additional restriction is applied.
* @param perms the {@code Permission} arguments which limit the
* scope of the caller's privileges. The number of arguments
* is variable.
*
* @return the value returned by the action's {@code run} method.
*
* @throws NullPointerException if action or perms or any element of
* perms is {@code null}
*
* @see #doPrivileged(PrivilegedAction)
* @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
* @see java.security.DomainCombiner
*
* @since 1.8
*/
@CallerSensitive
public static <T> T doPrivilegedWithCombiner(PrivilegedAction<T> action,
AccessControlContext context, Permission... perms) {
AccessControlContext parent = getContext();
DomainCombiner dc = parent.getCombiner();
if (dc == null && context != null) {
dc = context.getCombiner();
}
if (perms == null) {
throw new NullPointerException("null permissions parameter");
}
Class <?> caller = Reflection.getCallerClass();
return AccessController.doPrivileged(action, createWrapper(dc, caller,
parent, context, perms));
}
/**
* Performs the specified {@code PrivilegedExceptionAction} with
* privileges enabled. The action is performed with <i>all</i> of the
* permissions possessed by the caller's protection domain.
*
* <p> If the action's {@code run} method throws an <i>unchecked</i>
* exception, it will propagate through this method.
*
* <p> Note that any DomainCombiner associated with the current
* AccessControlContext will be ignored while the action is performed.
*
* @param <T> the type of the value returned by the
* PrivilegedExceptionAction's {@code run} method.
*
* @param action the action to be performed
*
* @return the value returned by the action's {@code run} method
*
* @exception PrivilegedActionException if the specified action's
* {@code run} method threw a <i>checked</i> exception
* @exception NullPointerException if the action is {@code null}
*
* @see #doPrivileged(PrivilegedAction)
* @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
* @see #doPrivilegedWithCombiner(PrivilegedExceptionAction)
* @see java.security.DomainCombiner
*/
@CallerSensitive
public static native <T> T
doPrivileged(PrivilegedExceptionAction<T> action)
throws PrivilegedActionException;
/**
* Performs the specified {@code PrivilegedExceptionAction} with
* privileges enabled. The action is performed with <i>all</i> of the
* permissions possessed by the caller's protection domain.
*
* <p> If the action's {@code run} method throws an <i>unchecked</i>
* exception, it will propagate through this method.
*
* <p> This method preserves the current AccessControlContext's
* DomainCombiner (which may be null) while the action is performed.
*
* @param <T> the type of the value returned by the
* PrivilegedExceptionAction's {@code run} method.
*
* @param action the action to be performed.
*
* @return the value returned by the action's {@code run} method
*
* @exception PrivilegedActionException if the specified action's
* {@code run} method threw a <i>checked</i> exception
* @exception NullPointerException if the action is {@code null}
*
* @see #doPrivileged(PrivilegedAction)
* @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext)
* @see java.security.DomainCombiner
*
* @since 1.6
*/
@CallerSensitive
public static <T> T doPrivilegedWithCombiner(PrivilegedExceptionAction<T> action)
throws PrivilegedActionException
{
AccessControlContext acc = getStackAccessControlContext();
if (acc == null) {
return AccessController.doPrivileged(action);
}
DomainCombiner dc = acc.getAssignedCombiner();
return AccessController.doPrivileged(action,
preserveCombiner(dc, Reflection.getCallerClass()));
}
/**
* preserve the combiner across the doPrivileged call
*/
private static AccessControlContext preserveCombiner(DomainCombiner combiner,
Class<?> caller)
{
return createWrapper(combiner, caller, null, null, null);
}
/**
* Create a wrapper to contain the limited privilege scope data.
*/
private static AccessControlContext
createWrapper(DomainCombiner combiner, Class<?> caller,
AccessControlContext parent, AccessControlContext context,
Permission[] perms)
{
ProtectionDomain callerPD = getCallerPD(caller);
// check if caller is authorized to create context
if (context != null && !context.isAuthorized() &&
System.getSecurityManager() != null &&
!callerPD.impliesCreateAccessControlContext())
{
return getInnocuousAcc();
} else {
return new AccessControlContext(callerPD, combiner, parent,
context, perms);
}
}
private static class AccHolder {
// An AccessControlContext with no granted permissions.
// Only initialized on demand when getInnocuousAcc() is called.
static final AccessControlContext innocuousAcc =
new AccessControlContext(new ProtectionDomain[] {
new ProtectionDomain(null, null) });
}
private static AccessControlContext getInnocuousAcc() {
return AccHolder.innocuousAcc;
}
private static ProtectionDomain getCallerPD(final Class <?> caller) {
ProtectionDomain callerPd = doPrivileged
(new PrivilegedAction<>() {
public ProtectionDomain run() {
return caller.getProtectionDomain();
}
});
return callerPd;
}
/**
* Performs the specified {@code PrivilegedExceptionAction} with
* privileges enabled and restricted by the specified
* {@code AccessControlContext}. The action is performed with the
* intersection of the permissions possessed by the caller's
* protection domain, and those possessed by the domains represented by the
* specified {@code AccessControlContext}.
* <p>
* If the action's {@code run} method throws an <i>unchecked</i>
* exception, it will propagate through this method.
* <p>
* If a security manager is installed and the specified
* {@code AccessControlContext} was not created by system code and the
* caller's {@code ProtectionDomain} has not been granted the
* {@literal "createAccessControlContext"}
* {@link java.security.SecurityPermission}, then the action is performed
* with no permissions.
*
* @param <T> the type of the value returned by the
* PrivilegedExceptionAction's {@code run} method.
* @param action the action to be performed
* @param context an <i>access control context</i>
* representing the restriction to be applied to the
* caller's domain's privileges before performing
* the specified action. If the context is
* {@code null}, then no additional restriction is applied.
*
* @return the value returned by the action's {@code run} method
*
* @exception PrivilegedActionException if the specified action's
* {@code run} method threw a <i>checked</i> exception
* @exception NullPointerException if the action is {@code null}
*
* @see #doPrivileged(PrivilegedAction)
* @see #doPrivileged(PrivilegedAction,AccessControlContext)
*/
@CallerSensitive
public static native <T> T
doPrivileged(PrivilegedExceptionAction<T> action,
AccessControlContext context)
throws PrivilegedActionException;
/**
* Performs the specified {@code PrivilegedExceptionAction} with
* privileges enabled and restricted by the specified
* {@code AccessControlContext} and with a privilege scope limited by
* specified {@code Permission} arguments.
*
* The action is performed with the intersection of the permissions
* possessed by the caller's protection domain, and those possessed
* by the domains represented by the specified
* {@code AccessControlContext}.
* <p>
* If the action's {@code run} method throws an (unchecked) exception,
* it will propagate through this method.
* <p>
* If a security manager is installed and the specified
* {@code AccessControlContext} was not created by system code and the
* caller's {@code ProtectionDomain} has not been granted the
* {@literal "createAccessControlContext"}
* {@link java.security.SecurityPermission}, then the action is performed
* with no permissions.
*
* @param <T> the type of the value returned by the
* PrivilegedExceptionAction's {@code run} method.
* @param action the action to be performed.
* @param context an <i>access control context</i>
* representing the restriction to be applied to the
* caller's domain's privileges before performing
* the specified action. If the context is
* {@code null},
* then no additional restriction is applied.
* @param perms the {@code Permission} arguments which limit the
* scope of the caller's privileges. The number of arguments
* is variable.
*
* @return the value returned by the action's {@code run} method.
*
* @throws PrivilegedActionException if the specified action's
* {@code run} method threw a <i>checked</i> exception
* @throws NullPointerException if action or perms or any element of
* perms is {@code null}
*
* @see #doPrivileged(PrivilegedAction)
* @see #doPrivileged(PrivilegedAction,AccessControlContext)
*
* @since 1.8
*/
@CallerSensitive
public static <T> T doPrivileged(PrivilegedExceptionAction<T> action,
AccessControlContext context, Permission... perms)
throws PrivilegedActionException
{
AccessControlContext parent = getContext();
if (perms == null) {
throw new NullPointerException("null permissions parameter");
}
Class <?> caller = Reflection.getCallerClass();
return AccessController.doPrivileged(action, createWrapper(null, caller, parent, context, perms));
}
/**
* Performs the specified {@code PrivilegedExceptionAction} with
* privileges enabled and restricted by the specified
* {@code AccessControlContext} and with a privilege scope limited by
* specified {@code Permission} arguments.
*
* The action is performed with the intersection of the permissions
* possessed by the caller's protection domain, and those possessed
* by the domains represented by the specified
* {@code AccessControlContext}.
* <p>
* If the action's {@code run} method throws an (unchecked) exception,
* it will propagate through this method.
*
* <p> This method preserves the current AccessControlContext's
* DomainCombiner (which may be null) while the action is performed.
* <p>
* If a security manager is installed and the specified
* {@code AccessControlContext} was not created by system code and the
* caller's {@code ProtectionDomain} has not been granted the
* {@literal "createAccessControlContext"}
* {@link java.security.SecurityPermission}, then the action is performed
* with no permissions.
*
* @param <T> the type of the value returned by the
* PrivilegedExceptionAction's {@code run} method.
* @param action the action to be performed.
* @param context an <i>access control context</i>
* representing the restriction to be applied to the
* caller's domain's privileges before performing
* the specified action. If the context is
* {@code null},
* then no additional restriction is applied.
* @param perms the {@code Permission} arguments which limit the
* scope of the caller's privileges. The number of arguments
* is variable.
*
* @return the value returned by the action's {@code run} method.
*
* @throws PrivilegedActionException if the specified action's
* {@code run} method threw a <i>checked</i> exception
* @throws NullPointerException if action or perms or any element of
* perms is {@code null}
*
* @see #doPrivileged(PrivilegedAction)
* @see #doPrivileged(PrivilegedAction,AccessControlContext)
* @see java.security.DomainCombiner
*
* @since 1.8
*/
@CallerSensitive
public static <T> T doPrivilegedWithCombiner(PrivilegedExceptionAction<T> action,
AccessControlContext context,
Permission... perms)
throws PrivilegedActionException
{
AccessControlContext parent = getContext();
DomainCombiner dc = parent.getCombiner();
if (dc == null && context != null) {
dc = context.getCombiner();
}
if (perms == null) {
throw new NullPointerException("null permissions parameter");
}
Class <?> caller = Reflection.getCallerClass();
return AccessController.doPrivileged(action, createWrapper(dc, caller,
parent, context, perms));
}
/**
* Returns the AccessControl context. i.e., it gets
* the protection domains of all the callers on the stack,
* starting at the first class with a non-null
* ProtectionDomain.
*
* @return the access control context based on the current stack or
* null if there was only privileged system code.
*/
private static native AccessControlContext getStackAccessControlContext();
/**
* Returns the "inherited" AccessControl context. This is the context
* that existed when the thread was created. Package private so
* AccessControlContext can use it.
*/
static native AccessControlContext getInheritedAccessControlContext();
/**
* This method takes a "snapshot" of the current calling context, which
* includes the current Thread's inherited AccessControlContext and any
* limited privilege scope, and places it in an AccessControlContext object.
* This context may then be checked at a later point, possibly in another thread.
*
* @see AccessControlContext
*
* @return the AccessControlContext based on the current context.
*/
public static AccessControlContext getContext()
{
AccessControlContext acc = getStackAccessControlContext();
if (acc == null) {
// all we had was privileged system code. We don't want
// to return null though, so we construct a real ACC.
return new AccessControlContext(null, true);
} else {
return acc.optimize();
}
}
/**
* Determines whether the access request indicated by the
* specified permission should be allowed or denied, based on
* the current AccessControlContext and security policy.
* This method quietly returns if the access request
* is permitted, or throws an AccessControlException otherwise. The
* getPermission method of the AccessControlException returns the
* {@code perm} Permission object instance.
*
* @param perm the requested permission.
*
* @exception AccessControlException if the specified permission
* is not permitted, based on the current security policy.
* @exception NullPointerException if the specified permission
* is {@code null} and is checked based on the
* security policy currently in effect.
*/
public static void checkPermission(Permission perm)
throws AccessControlException
{
//System.err.println("checkPermission "+perm);
//Thread.currentThread().dumpStack();
if (perm == null) {
throw new NullPointerException("permission can't be null");
}
AccessControlContext stack = getStackAccessControlContext();
// if context is null, we had privileged system code on the stack.
if (stack == null) {
Debug debug = AccessControlContext.getDebug();
boolean dumpDebug = false;
if (debug != null) {
dumpDebug = !Debug.isOn("codebase=");
dumpDebug &= !Debug.isOn("permission=") ||
Debug.isOn("permission=" + perm.getClass().getCanonicalName());
}
if (dumpDebug && Debug.isOn("stack")) {
Thread.dumpStack();
}
if (dumpDebug && Debug.isOn("domain")) {
debug.println("domain (context is null)");
}
if (dumpDebug) {
debug.println("access allowed "+perm);
}
return;
}
AccessControlContext acc = stack.optimize();
acc.checkPermission(perm);
}
}

View file

@ -0,0 +1,108 @@
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
import java.util.Set;
/**
* This interface specifies constraints for cryptographic algorithms,
* keys (key sizes), and other algorithm parameters.
* <p>
* {@code AlgorithmConstraints} objects are immutable. An implementation
* of this interface should not provide methods that can change the state
* of an instance once it has been created.
* <p>
* Note that {@code AlgorithmConstraints} can be used to represent the
* restrictions described by the security properties
* {@code jdk.certpath.disabledAlgorithms} and
* {@code jdk.tls.disabledAlgorithms}, or could be used by a
* concrete {@code PKIXCertPathChecker} to check whether a specified
* certificate in the certification path contains the required algorithm
* constraints.
*
* @see javax.net.ssl.SSLParameters#getAlgorithmConstraints
* @see javax.net.ssl.SSLParameters#setAlgorithmConstraints(AlgorithmConstraints)
*
* @since 1.7
*/
public interface AlgorithmConstraints {
/**
* Determines whether an algorithm is granted permission for the
* specified cryptographic primitives.
*
* @param primitives a set of cryptographic primitives
* @param algorithm the algorithm name
* @param parameters the algorithm parameters, or null if no additional
* parameters
*
* @return true if the algorithm is permitted and can be used for all
* of the specified cryptographic primitives
*
* @throws IllegalArgumentException if primitives or algorithm is null
* or empty
*/
public boolean permits(Set<CryptoPrimitive> primitives,
String algorithm, AlgorithmParameters parameters);
/**
* Determines whether a key is granted permission for the specified
* cryptographic primitives.
* <p>
* This method is usually used to check key size and key usage.
*
* @param primitives a set of cryptographic primitives
* @param key the key
*
* @return true if the key can be used for all of the specified
* cryptographic primitives
*
* @throws IllegalArgumentException if primitives is null or empty,
* or the key is null
*/
public boolean permits(Set<CryptoPrimitive> primitives, Key key);
/**
* Determines whether an algorithm and the corresponding key are granted
* permission for the specified cryptographic primitives.
*
* @param primitives a set of cryptographic primitives
* @param algorithm the algorithm name
* @param key the key
* @param parameters the algorithm parameters, or null if no additional
* parameters
*
* @return true if the key and the algorithm can be used for all of the
* specified cryptographic primitives
*
* @throws IllegalArgumentException if primitives or algorithm is null
* or empty, or the key is null
*/
public boolean permits(Set<CryptoPrimitive> primitives,
String algorithm, Key key, AlgorithmParameters parameters);
}

View file

@ -0,0 +1,369 @@
/*
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Objects;
/**
* The {@code AlgorithmParameterGenerator} class is used to generate a
* set of
* parameters to be used with a certain algorithm. Parameter generators
* are constructed using the {@code getInstance} factory methods
* (static methods that return instances of a given class).
*
* <P>The object that will generate the parameters can be initialized
* in two different ways: in an algorithm-independent manner, or in an
* algorithm-specific manner:
*
* <ul>
* <li>The algorithm-independent approach uses the fact that all parameter
* generators share the concept of a "size" and a
* source of randomness. The measure of size is universally shared
* by all algorithm parameters, though it is interpreted differently
* for different algorithms. For example, in the case of parameters for
* the <i>DSA</i> algorithm, "size" corresponds to the size
* of the prime modulus (in bits).
* When using this approach, algorithm-specific parameter generation
* values - if any - default to some standard values, unless they can be
* derived from the specified size.
*
* <li>The other approach initializes a parameter generator object
* using algorithm-specific semantics, which are represented by a set of
* algorithm-specific parameter generation values. To generate
* Diffie-Hellman system parameters, for example, the parameter generation
* values usually
* consist of the size of the prime modulus and the size of the
* random exponent, both specified in number of bits.
* </ul>
*
* <P>In case the client does not explicitly initialize the
* AlgorithmParameterGenerator (via a call to an {@code init} method),
* each provider must supply (and document) a default initialization.
* See the Keysize Restriction sections of the
* {@extLink security_guide_jdk_providers JDK Providers}
* document for information on the AlgorithmParameterGenerator defaults
* used by JDK providers.
* However, note that defaults may vary across different providers.
* Additionally, the default value for a provider may change in a future
* version. Therefore, it is recommended to explicitly initialize the
* AlgorithmParameterGenerator instead of relying on provider-specific defaults.
*
* <p> Every implementation of the Java platform is required to support the
* following standard {@code AlgorithmParameterGenerator} algorithms and
* keysizes in parentheses:
* <ul>
* <li>{@code DiffieHellman} (1024, 2048)</li>
* <li>{@code DSA} (1024, 2048)</li>
* </ul>
* These algorithms are described in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#algorithmparametergenerator-algorithms">
* AlgorithmParameterGenerator section</a> of the
* Java Security Standard Algorithm Names Specification.
* Consult the release documentation for your implementation to see if any
* other algorithms are supported.
*
* @author Jan Luehe
*
*
* @see AlgorithmParameters
* @see java.security.spec.AlgorithmParameterSpec
*
* @since 1.2
*/
public class AlgorithmParameterGenerator {
// The provider
private Provider provider;
// The provider implementation (delegate)
private AlgorithmParameterGeneratorSpi paramGenSpi;
// The algorithm
private String algorithm;
/**
* Creates an AlgorithmParameterGenerator object.
*
* @param paramGenSpi the delegate
* @param provider the provider
* @param algorithm the algorithm
*/
protected AlgorithmParameterGenerator
(AlgorithmParameterGeneratorSpi paramGenSpi, Provider provider,
String algorithm) {
this.paramGenSpi = paramGenSpi;
this.provider = provider;
this.algorithm = algorithm;
}
/**
* Returns the standard name of the algorithm this parameter
* generator is associated with.
*
* @return the string name of the algorithm.
*/
public final String getAlgorithm() {
return this.algorithm;
}
/**
* Returns an AlgorithmParameterGenerator object for generating
* a set of parameters to be used with the specified algorithm.
*
* <p> This method traverses the list of registered security Providers,
* starting with the most preferred Provider.
* A new AlgorithmParameterGenerator object encapsulating the
* AlgorithmParameterGeneratorSpi implementation from the first
* Provider that supports the specified algorithm is returned.
*
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @implNote
* The JDK Reference Implementation additionally uses the
* {@code jdk.security.provider.preferred}
* {@link Security#getProperty(String) Security} property to determine
* the preferred provider order for the specified algorithm. This
* may be different than the order of providers returned by
* {@link Security#getProviders() Security.getProviders()}.
*
* @param algorithm the name of the algorithm this
* parameter generator is associated with.
* See the AlgorithmParameterGenerator section in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#algorithmparametergenerator-algorithms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard algorithm names.
*
* @return the new {@code AlgorithmParameterGenerator} object
*
* @throws NoSuchAlgorithmException if no {@code Provider} supports an
* {@code AlgorithmParameterGeneratorSpi} implementation for the
* specified algorithm
*
* @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see Provider
*/
public static AlgorithmParameterGenerator getInstance(String algorithm)
throws NoSuchAlgorithmException {
Objects.requireNonNull(algorithm, "null algorithm name");
try {
Object[] objs = Security.getImpl(algorithm,
"AlgorithmParameterGenerator",
(String)null);
return new AlgorithmParameterGenerator
((AlgorithmParameterGeneratorSpi)objs[0],
(Provider)objs[1],
algorithm);
} catch(NoSuchProviderException e) {
throw new NoSuchAlgorithmException(algorithm + " not found");
}
}
/**
* Returns an AlgorithmParameterGenerator object for generating
* a set of parameters to be used with the specified algorithm.
*
* <p> A new AlgorithmParameterGenerator object encapsulating the
* AlgorithmParameterGeneratorSpi implementation from the specified provider
* is returned. The specified provider must be registered
* in the security provider list.
*
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param algorithm the name of the algorithm this
* parameter generator is associated with.
* See the AlgorithmParameterGenerator section in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#algorithmparametergenerator-algorithms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard algorithm names.
*
* @param provider the string name of the Provider.
*
* @return the new {@code AlgorithmParameterGenerator} object
*
* @throws IllegalArgumentException if the provider name is {@code null}
* or empty
*
* @throws NoSuchAlgorithmException if an
* {@code AlgorithmParameterGeneratorSpi}
* implementation for the specified algorithm is not
* available from the specified provider
*
* @throws NoSuchProviderException if the specified provider is not
* registered in the security provider list
*
* @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see Provider
*/
public static AlgorithmParameterGenerator getInstance(String algorithm,
String provider)
throws NoSuchAlgorithmException, NoSuchProviderException
{
Objects.requireNonNull(algorithm, "null algorithm name");
if (provider == null || provider.length() == 0)
throw new IllegalArgumentException("missing provider");
Object[] objs = Security.getImpl(algorithm,
"AlgorithmParameterGenerator",
provider);
return new AlgorithmParameterGenerator
((AlgorithmParameterGeneratorSpi)objs[0], (Provider)objs[1],
algorithm);
}
/**
* Returns an AlgorithmParameterGenerator object for generating
* a set of parameters to be used with the specified algorithm.
*
* <p> A new AlgorithmParameterGenerator object encapsulating the
* AlgorithmParameterGeneratorSpi implementation from the specified Provider
* object is returned. Note that the specified Provider object
* does not have to be registered in the provider list.
*
* @param algorithm the string name of the algorithm this
* parameter generator is associated with.
* See the AlgorithmParameterGenerator section in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#algorithmparametergenerator-algorithms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard algorithm names.
*
* @param provider the {@code Provider} object.
*
* @return the new {@code AlgorithmParameterGenerator} object
*
* @throws IllegalArgumentException if the specified provider is
* {@code null}
*
* @throws NoSuchAlgorithmException if an
* {@code AlgorithmParameterGeneratorSpi}
* implementation for the specified algorithm is not available
* from the specified {@code Provider} object
*
* @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see Provider
*
* @since 1.4
*/
public static AlgorithmParameterGenerator getInstance(String algorithm,
Provider provider)
throws NoSuchAlgorithmException
{
Objects.requireNonNull(algorithm, "null algorithm name");
if (provider == null)
throw new IllegalArgumentException("missing provider");
Object[] objs = Security.getImpl(algorithm,
"AlgorithmParameterGenerator",
provider);
return new AlgorithmParameterGenerator
((AlgorithmParameterGeneratorSpi)objs[0], (Provider)objs[1],
algorithm);
}
/**
* Returns the provider of this algorithm parameter generator object.
*
* @return the provider of this algorithm parameter generator object
*/
public final Provider getProvider() {
return this.provider;
}
/**
* Initializes this parameter generator for a certain size.
* To create the parameters, the {@code SecureRandom}
* implementation of the highest-priority installed provider is used as
* the source of randomness.
* (If none of the installed providers supply an implementation of
* {@code SecureRandom}, a system-provided source of randomness is
* used.)
*
* @param size the size (number of bits).
*/
public final void init(int size) {
paramGenSpi.engineInit(size, new SecureRandom());
}
/**
* Initializes this parameter generator for a certain size and source
* of randomness.
*
* @param size the size (number of bits).
* @param random the source of randomness.
*/
public final void init(int size, SecureRandom random) {
paramGenSpi.engineInit(size, random);
}
/**
* Initializes this parameter generator with a set of algorithm-specific
* parameter generation values.
* To generate the parameters, the {@code SecureRandom}
* implementation of the highest-priority installed provider is used as
* the source of randomness.
* (If none of the installed providers supply an implementation of
* {@code SecureRandom}, a system-provided source of randomness is
* used.)
*
* @param genParamSpec the set of algorithm-specific parameter generation values.
*
* @exception InvalidAlgorithmParameterException if the given parameter
* generation values are inappropriate for this parameter generator.
*/
public final void init(AlgorithmParameterSpec genParamSpec)
throws InvalidAlgorithmParameterException {
paramGenSpi.engineInit(genParamSpec, new SecureRandom());
}
/**
* Initializes this parameter generator with a set of algorithm-specific
* parameter generation values.
*
* @param genParamSpec the set of algorithm-specific parameter generation values.
* @param random the source of randomness.
*
* @exception InvalidAlgorithmParameterException if the given parameter
* generation values are inappropriate for this parameter generator.
*/
public final void init(AlgorithmParameterSpec genParamSpec,
SecureRandom random)
throws InvalidAlgorithmParameterException {
paramGenSpi.engineInit(genParamSpec, random);
}
/**
* Generates the parameters.
*
* @return the new AlgorithmParameters object.
*/
public final AlgorithmParameters generateParameters() {
return paramGenSpi.engineGenerateParameters();
}
}

View file

@ -0,0 +1,92 @@
/*
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
import java.security.spec.AlgorithmParameterSpec;
/**
* This class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
* for the {@code AlgorithmParameterGenerator} class, which
* is used to generate a set of parameters to be used with a certain algorithm.
*
* <p> All the abstract methods in this class must be implemented by each
* cryptographic service provider who wishes to supply the implementation
* of a parameter generator for a particular algorithm.
*
* <p> In case the client does not explicitly initialize the
* AlgorithmParameterGenerator (via a call to an {@code engineInit}
* method), each provider must supply (and document) a default initialization.
* See the Keysize Restriction sections of the
* {@extLink security_guide_jdk_providers JDK Providers}
* document for information on the AlgorithmParameterGenerator defaults
* used by JDK providers.
* However, note that defaults may vary across different providers.
* Additionally, the default value for a provider may change in a future
* version. Therefore, it is recommended to explicitly initialize the
* AlgorithmParameterGenerator instead of relying on provider-specific defaults.
*
* @author Jan Luehe
*
*
* @see AlgorithmParameterGenerator
* @see AlgorithmParameters
* @see java.security.spec.AlgorithmParameterSpec
*
* @since 1.2
*/
public abstract class AlgorithmParameterGeneratorSpi {
/**
* Initializes this parameter generator for a certain size
* and source of randomness.
*
* @param size the size (number of bits).
* @param random the source of randomness.
*/
protected abstract void engineInit(int size, SecureRandom random);
/**
* Initializes this parameter generator with a set of
* algorithm-specific parameter generation values.
*
* @param genParamSpec the set of algorithm-specific parameter generation values.
* @param random the source of randomness.
*
* @exception InvalidAlgorithmParameterException if the given parameter
* generation values are inappropriate for this parameter generator.
*/
protected abstract void engineInit(AlgorithmParameterSpec genParamSpec,
SecureRandom random)
throws InvalidAlgorithmParameterException;
/**
* Generates the parameters.
*
* @return the new AlgorithmParameters object.
*/
protected abstract AlgorithmParameters engineGenerateParameters();
}

View file

@ -0,0 +1,418 @@
/*
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
import java.io.*;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.InvalidParameterSpecException;
import java.util.Objects;
/**
* This class is used as an opaque representation of cryptographic parameters.
*
* <p>An {@code AlgorithmParameters} object for managing the parameters
* for a particular algorithm can be obtained by
* calling one of the {@code getInstance} factory methods
* (static methods that return instances of a given class).
*
* <p>Once an {@code AlgorithmParameters} object is obtained, it must be
* initialized via a call to {@code init}, using an appropriate parameter
* specification or parameter encoding.
*
* <p>A transparent parameter specification is obtained from an
* {@code AlgorithmParameters} object via a call to
* {@code getParameterSpec}, and a byte encoding of the parameters is
* obtained via a call to {@code getEncoded}.
*
* <p> Every implementation of the Java platform is required to support the
* following standard {@code AlgorithmParameters} algorithms:
* <ul>
* <li>{@code AES}</li>
* <li>{@code DES}</li>
* <li>{@code DESede}</li>
* <li>{@code DiffieHellman}</li>
* <li>{@code DSA}</li>
* </ul>
* These algorithms are described in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#algorithmparameters-algorithms">
* AlgorithmParameters section</a> of the
* Java Security Standard Algorithm Names Specification.
* Consult the release documentation for your implementation to see if any
* other algorithms are supported.
*
* @author Jan Luehe
*
*
* @see java.security.spec.AlgorithmParameterSpec
* @see java.security.spec.DSAParameterSpec
* @see KeyPairGenerator
*
* @since 1.2
*/
public class AlgorithmParameters {
// The provider
private Provider provider;
// The provider implementation (delegate)
private AlgorithmParametersSpi paramSpi;
// The algorithm
private String algorithm;
// Has this object been initialized?
private boolean initialized = false;
/**
* Creates an AlgorithmParameters object.
*
* @param paramSpi the delegate
* @param provider the provider
* @param algorithm the algorithm
*/
protected AlgorithmParameters(AlgorithmParametersSpi paramSpi,
Provider provider, String algorithm)
{
this.paramSpi = paramSpi;
this.provider = provider;
this.algorithm = algorithm;
}
/**
* Returns the name of the algorithm associated with this parameter object.
*
* @return the algorithm name.
*/
public final String getAlgorithm() {
return this.algorithm;
}
/**
* Returns a parameter object for the specified algorithm.
*
* <p> This method traverses the list of registered security Providers,
* starting with the most preferred Provider.
* A new AlgorithmParameters object encapsulating the
* AlgorithmParametersSpi implementation from the first
* Provider that supports the specified algorithm is returned.
*
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
*
* <p> The returned parameter object must be initialized via a call to
* {@code init}, using an appropriate parameter specification or
* parameter encoding.
*
* @implNote
* The JDK Reference Implementation additionally uses the
* {@code jdk.security.provider.preferred}
* {@link Security#getProperty(String) Security} property to determine
* the preferred provider order for the specified algorithm. This
* may be different than the order of providers returned by
* {@link Security#getProviders() Security.getProviders()}.
*
* @param algorithm the name of the algorithm requested.
* See the AlgorithmParameters section in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#algorithmparameters-algorithms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard algorithm names.
*
* @return the new parameter object
*
* @throws NoSuchAlgorithmException if no {@code Provider} supports an
* {@code AlgorithmParametersSpi} implementation for the
* specified algorithm
*
* @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see Provider
*/
public static AlgorithmParameters getInstance(String algorithm)
throws NoSuchAlgorithmException {
Objects.requireNonNull(algorithm, "null algorithm name");
try {
Object[] objs = Security.getImpl(algorithm, "AlgorithmParameters",
(String)null);
return new AlgorithmParameters((AlgorithmParametersSpi)objs[0],
(Provider)objs[1],
algorithm);
} catch(NoSuchProviderException e) {
throw new NoSuchAlgorithmException(algorithm + " not found");
}
}
/**
* Returns a parameter object for the specified algorithm.
*
* <p> A new AlgorithmParameters object encapsulating the
* AlgorithmParametersSpi implementation from the specified provider
* is returned. The specified provider must be registered
* in the security provider list.
*
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
*
* <p>The returned parameter object must be initialized via a call to
* {@code init}, using an appropriate parameter specification or
* parameter encoding.
*
* @param algorithm the name of the algorithm requested.
* See the AlgorithmParameters section in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#algorithmparameters-algorithms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard algorithm names.
*
* @param provider the name of the provider.
*
* @return the new parameter object
*
* @throws IllegalArgumentException if the provider name is {@code null}
* or empty
*
* @throws NoSuchAlgorithmException if an {@code AlgorithmParametersSpi}
* implementation for the specified algorithm is not
* available from the specified provider
*
* @throws NoSuchProviderException if the specified provider is not
* registered in the security provider list
*
* @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see Provider
*/
public static AlgorithmParameters getInstance(String algorithm,
String provider)
throws NoSuchAlgorithmException, NoSuchProviderException
{
Objects.requireNonNull(algorithm, "null algorithm name");
if (provider == null || provider.length() == 0)
throw new IllegalArgumentException("missing provider");
Object[] objs = Security.getImpl(algorithm, "AlgorithmParameters",
provider);
return new AlgorithmParameters((AlgorithmParametersSpi)objs[0],
(Provider)objs[1],
algorithm);
}
/**
* Returns a parameter object for the specified algorithm.
*
* <p> A new AlgorithmParameters object encapsulating the
* AlgorithmParametersSpi implementation from the specified Provider
* object is returned. Note that the specified Provider object
* does not have to be registered in the provider list.
*
* <p>The returned parameter object must be initialized via a call to
* {@code init}, using an appropriate parameter specification or
* parameter encoding.
*
* @param algorithm the name of the algorithm requested.
* See the AlgorithmParameters section in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#algorithmparameters-algorithms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard algorithm names.
*
* @param provider the name of the provider.
*
* @return the new parameter object
*
* @throws IllegalArgumentException if the provider is {@code null}
*
* @throws NoSuchAlgorithmException if an
* {@code AlgorithmParameterGeneratorSpi}
* implementation for the specified algorithm is not available
* from the specified {@code Provider} object
*
* @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see Provider
*
* @since 1.4
*/
public static AlgorithmParameters getInstance(String algorithm,
Provider provider)
throws NoSuchAlgorithmException
{
Objects.requireNonNull(algorithm, "null algorithm name");
if (provider == null)
throw new IllegalArgumentException("missing provider");
Object[] objs = Security.getImpl(algorithm, "AlgorithmParameters",
provider);
return new AlgorithmParameters((AlgorithmParametersSpi)objs[0],
(Provider)objs[1],
algorithm);
}
/**
* Returns the provider of this parameter object.
*
* @return the provider of this parameter object
*/
public final Provider getProvider() {
return this.provider;
}
/**
* Initializes this parameter object using the parameters
* specified in {@code paramSpec}.
*
* @param paramSpec the parameter specification.
*
* @exception InvalidParameterSpecException if the given parameter
* specification is inappropriate for the initialization of this parameter
* object, or if this parameter object has already been initialized.
*/
public final void init(AlgorithmParameterSpec paramSpec)
throws InvalidParameterSpecException
{
if (this.initialized)
throw new InvalidParameterSpecException("already initialized");
paramSpi.engineInit(paramSpec);
this.initialized = true;
}
/**
* Imports the specified parameters and decodes them according to the
* primary decoding format for parameters. The primary decoding
* format for parameters is ASN.1, if an ASN.1 specification for this type
* of parameters exists.
*
* @param params the encoded parameters.
*
* @exception IOException on decoding errors, or if this parameter object
* has already been initialized.
*/
public final void init(byte[] params) throws IOException {
if (this.initialized)
throw new IOException("already initialized");
paramSpi.engineInit(params);
this.initialized = true;
}
/**
* Imports the parameters from {@code params} and decodes them
* according to the specified decoding scheme.
* If {@code format} is null, the
* primary decoding format for parameters is used. The primary decoding
* format is ASN.1, if an ASN.1 specification for these parameters
* exists.
*
* @param params the encoded parameters.
*
* @param format the name of the decoding scheme.
*
* @exception IOException on decoding errors, or if this parameter object
* has already been initialized.
*/
public final void init(byte[] params, String format) throws IOException {
if (this.initialized)
throw new IOException("already initialized");
paramSpi.engineInit(params, format);
this.initialized = true;
}
/**
* Returns a (transparent) specification of this parameter object.
* {@code paramSpec} identifies the specification class in which
* the parameters should be returned. It could, for example, be
* {@code DSAParameterSpec.class}, to indicate that the
* parameters should be returned in an instance of the
* {@code DSAParameterSpec} class.
*
* @param <T> the type of the parameter specification to be returrned
* @param paramSpec the specification class in which
* the parameters should be returned.
*
* @return the parameter specification.
*
* @exception InvalidParameterSpecException if the requested parameter
* specification is inappropriate for this parameter object, or if this
* parameter object has not been initialized.
*/
public final <T extends AlgorithmParameterSpec>
T getParameterSpec(Class<T> paramSpec)
throws InvalidParameterSpecException
{
if (this.initialized == false) {
throw new InvalidParameterSpecException("not initialized");
}
return paramSpi.engineGetParameterSpec(paramSpec);
}
/**
* Returns the parameters in their primary encoding format.
* The primary encoding format for parameters is ASN.1, if an ASN.1
* specification for this type of parameters exists.
*
* @return the parameters encoded using their primary encoding format.
*
* @exception IOException on encoding errors, or if this parameter object
* has not been initialized.
*/
public final byte[] getEncoded() throws IOException
{
if (this.initialized == false) {
throw new IOException("not initialized");
}
return paramSpi.engineGetEncoded();
}
/**
* Returns the parameters encoded in the specified scheme.
* If {@code format} is null, the
* primary encoding format for parameters is used. The primary encoding
* format is ASN.1, if an ASN.1 specification for these parameters
* exists.
*
* @param format the name of the encoding format.
*
* @return the parameters encoded using the specified encoding scheme.
*
* @exception IOException on encoding errors, or if this parameter object
* has not been initialized.
*/
public final byte[] getEncoded(String format) throws IOException
{
if (this.initialized == false) {
throw new IOException("not initialized");
}
return paramSpi.engineGetEncoded(format);
}
/**
* Returns a formatted string describing the parameters.
*
* @return a formatted string describing the parameters, or null if this
* parameter object has not been initialized.
*/
public final String toString() {
if (this.initialized == false) {
return null;
}
return paramSpi.engineToString();
}
}

View file

@ -0,0 +1,153 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
import java.io.*;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.InvalidParameterSpecException;
/**
* This class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
* for the {@code AlgorithmParameters} class, which is used to manage
* algorithm parameters.
*
* <p> All the abstract methods in this class must be implemented by each
* cryptographic service provider who wishes to supply parameter management
* for a particular algorithm.
*
* @author Jan Luehe
*
*
* @see AlgorithmParameters
* @see java.security.spec.AlgorithmParameterSpec
* @see java.security.spec.DSAParameterSpec
*
* @since 1.2
*/
public abstract class AlgorithmParametersSpi {
/**
* Initializes this parameters object using the parameters
* specified in {@code paramSpec}.
*
* @param paramSpec the parameter specification.
*
* @exception InvalidParameterSpecException if the given parameter
* specification is inappropriate for the initialization of this parameter
* object.
*/
protected abstract void engineInit(AlgorithmParameterSpec paramSpec)
throws InvalidParameterSpecException;
/**
* Imports the specified parameters and decodes them
* according to the primary decoding format for parameters.
* The primary decoding format for parameters is ASN.1, if an ASN.1
* specification for this type of parameters exists.
*
* @param params the encoded parameters.
*
* @exception IOException on decoding errors
*/
protected abstract void engineInit(byte[] params)
throws IOException;
/**
* Imports the parameters from {@code params} and
* decodes them according to the specified decoding format.
* If {@code format} is null, the
* primary decoding format for parameters is used. The primary decoding
* format is ASN.1, if an ASN.1 specification for these parameters
* exists.
*
* @param params the encoded parameters.
*
* @param format the name of the decoding format.
*
* @exception IOException on decoding errors
*/
protected abstract void engineInit(byte[] params, String format)
throws IOException;
/**
* Returns a (transparent) specification of this parameters
* object.
* {@code paramSpec} identifies the specification class in which
* the parameters should be returned. It could, for example, be
* {@code DSAParameterSpec.class}, to indicate that the
* parameters should be returned in an instance of the
* {@code DSAParameterSpec} class.
*
* @param <T> the type of the parameter specification to be returned
*
* @param paramSpec the specification class in which
* the parameters should be returned.
*
* @return the parameter specification.
*
* @exception InvalidParameterSpecException if the requested parameter
* specification is inappropriate for this parameter object.
*/
protected abstract
<T extends AlgorithmParameterSpec>
T engineGetParameterSpec(Class<T> paramSpec)
throws InvalidParameterSpecException;
/**
* Returns the parameters in their primary encoding format.
* The primary encoding format for parameters is ASN.1, if an ASN.1
* specification for this type of parameters exists.
*
* @return the parameters encoded using their primary encoding format.
*
* @exception IOException on encoding errors.
*/
protected abstract byte[] engineGetEncoded() throws IOException;
/**
* Returns the parameters encoded in the specified format.
* If {@code format} is null, the
* primary encoding format for parameters is used. The primary encoding
* format is ASN.1, if an ASN.1 specification for these parameters
* exists.
*
* @param format the name of the encoding format.
*
* @return the parameters encoded using the specified encoding scheme.
*
* @exception IOException on encoding errors.
*/
protected abstract byte[] engineGetEncoded(String format)
throws IOException;
/**
* Returns a formatted string describing the parameters.
*
* @return a formatted string describing the parameters.
*/
protected abstract String engineToString();
}

View file

@ -0,0 +1,229 @@
/*
* Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
import java.security.*;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.StringTokenizer;
import sun.security.util.SecurityConstants;
/**
* The AllPermission is a permission that implies all other permissions.
* <p>
* <b>Note:</b> Granting AllPermission should be done with extreme care,
* as it implies all other permissions. Thus, it grants code the ability
* to run with security
* disabled. Extreme caution should be taken before granting such
* a permission to code. This permission should be used only during testing,
* or in extremely rare cases where an application or applet is
* completely trusted and adding the necessary permissions to the policy
* is prohibitively cumbersome.
*
* @see java.security.Permission
* @see java.security.AccessController
* @see java.security.Permissions
* @see java.security.PermissionCollection
* @see java.lang.SecurityManager
*
*
* @author Roland Schemers
* @since 1.2
*
* @serial exclude
*/
public final class AllPermission extends Permission {
private static final long serialVersionUID = -2916474571451318075L;
/**
* Creates a new AllPermission object.
*/
public AllPermission() {
super("<all permissions>");
}
/**
* Creates a new AllPermission object. This
* constructor exists for use by the {@code Policy} object
* to instantiate new Permission objects.
*
* @param name ignored
* @param actions ignored.
*/
public AllPermission(String name, String actions) {
this();
}
/**
* Checks if the specified permission is "implied" by
* this object. This method always returns true.
*
* @param p the permission to check against.
*
* @return return
*/
public boolean implies(Permission p) {
return true;
}
/**
* Checks two AllPermission objects for equality. Two AllPermission
* objects are always equal.
*
* @param obj the object we are testing for equality with this object.
* @return true if {@code obj} is an AllPermission, false otherwise.
*/
public boolean equals(Object obj) {
return (obj instanceof AllPermission);
}
/**
* Returns the hash code value for this object.
*
* @return a hash code value for this object.
*/
public int hashCode() {
return 1;
}
/**
* Returns the canonical string representation of the actions.
*
* @return the actions.
*/
public String getActions() {
return "<all actions>";
}
/**
* Returns a new PermissionCollection object for storing AllPermission
* objects.
*
* @return a new PermissionCollection object suitable for
* storing AllPermissions.
*/
public PermissionCollection newPermissionCollection() {
return new AllPermissionCollection();
}
}
/**
* A AllPermissionCollection stores a collection
* of AllPermission permissions. AllPermission objects
* must be stored in a manner that allows them to be inserted in any
* order, but enable the implies function to evaluate the implies
* method in an efficient (and consistent) manner.
*
* @see java.security.Permission
* @see java.security.Permissions
*
*
* @author Roland Schemers
*
* @serial include
*/
final class AllPermissionCollection
extends PermissionCollection
implements java.io.Serializable
{
// use serialVersionUID from JDK 1.2.2 for interoperability
private static final long serialVersionUID = -4023755556366636806L;
private boolean all_allowed; // true if any all permissions have been added
/**
* Create an empty AllPermissions object.
*
*/
public AllPermissionCollection() {
all_allowed = false;
}
/**
* Adds a permission to the AllPermissions. The key for the hash is
* permission.path.
*
* @param permission the Permission object to add.
*
* @exception IllegalArgumentException - if the permission is not a
* AllPermission
*
* @exception SecurityException - if this AllPermissionCollection object
* has been marked readonly
*/
public void add(Permission permission) {
if (! (permission instanceof AllPermission))
throw new IllegalArgumentException("invalid permission: "+
permission);
if (isReadOnly())
throw new SecurityException("attempt to add a Permission to a readonly PermissionCollection");
all_allowed = true; // No sync; staleness OK
}
/**
* Check and see if this set of permissions implies the permissions
* expressed in "permission".
*
* @param permission the Permission object to compare
*
* @return always returns true.
*/
public boolean implies(Permission permission) {
return all_allowed; // No sync; staleness OK
}
/**
* Returns an enumeration of all the AllPermission objects in the
* container.
*
* @return an enumeration of all the AllPermission objects.
*/
public Enumeration<Permission> elements() {
return new Enumeration<>() {
private boolean hasMore = all_allowed;
public boolean hasMoreElements() {
return hasMore;
}
public Permission nextElement() {
hasMore = false;
return SecurityConstants.ALL_PERMISSION;
}
};
}
}

View file

@ -0,0 +1,149 @@
/*
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
import javax.security.auth.Subject;
import javax.security.auth.login.LoginException;
import javax.security.auth.callback.CallbackHandler;
/**
* This class defines login and logout methods for a provider.
*
* <p> While callers may invoke {@code login} directly,
* the provider may also invoke {@code login} on behalf of callers
* if it determines that a login must be performed
* prior to certain operations.
*
* @since 1.5
*/
public abstract class AuthProvider extends Provider {
private static final long serialVersionUID = 4197859053084546461L;
/**
* Constructs a provider with the specified name, version number,
* and information.
*
* @param name the provider name.
* @param version the provider version number.
* @param info a description of the provider and its services.
* @deprecated use {@link #AuthProvider(String, String, String)} instead.
*/
@Deprecated(since="9")
protected AuthProvider(String name, double version, String info) {
super(name, Double.toString(version), info);
}
/**
* Constructs a provider with the specified name, version string,
* and information.
*
* @param name the provider name.
* @param versionStr the provider version string.
* @param info a description of the provider and its services.
* @since 9
*/
protected AuthProvider(String name, String versionStr, String info) {
super(name, versionStr, info);
}
/**
* Log in to this provider.
*
* <p> The provider relies on a {@code CallbackHandler}
* to obtain authentication information from the caller
* (a PIN, for example). If the caller passes a {@code null}
* handler to this method, the provider uses the handler set in the
* {@code setCallbackHandler} method.
* If no handler was set in that method, the provider queries the
* <i>auth.login.defaultCallbackHandler</i> security property
* for the fully qualified class name of a default handler implementation.
* If the security property is not set,
* the provider is assumed to have alternative means
* for obtaining authentication information.
*
* @param subject the {@code Subject} which may contain
* principals/credentials used for authentication,
* or may be populated with additional principals/credentials
* after successful authentication has completed.
* This parameter may be {@code null}.
* @param handler the {@code CallbackHandler} used by
* this provider to obtain authentication information
* from the caller, which may be {@code null}
*
* @throws IllegalStateException if the provider requires configuration
* and {@link configure} has not been called
* @throws LoginException if the login operation fails
* @throws SecurityException if the caller does not pass a
* security check for
* {@code SecurityPermission("authProvider.name")},
* where {@code name} is the value returned by
* this provider's {@code getName} method
*/
public abstract void login(Subject subject, CallbackHandler handler)
throws LoginException;
/**
* Log out from this provider.
*
* @throws IllegalStateException if the provider requires configuration
* and {@link configure} has not been called
* @throws LoginException if the logout operation fails
* @throws SecurityException if the caller does not pass a
* security check for
* {@code SecurityPermission("authProvider.name")},
* where {@code name} is the value returned by
* this provider's {@code getName} method
*/
public abstract void logout() throws LoginException;
/**
* Set a {@code CallbackHandler}.
*
* <p> The provider uses this handler if one is not passed to the
* {@code login} method. The provider also uses this handler
* if it invokes {@code login} on behalf of callers.
* In either case if a handler is not set via this method,
* the provider queries the
* <i>auth.login.defaultCallbackHandler</i> security property
* for the fully qualified class name of a default handler implementation.
* If the security property is not set,
* the provider is assumed to have alternative means
* for obtaining authentication information.
*
* @param handler a {@code CallbackHandler} for obtaining
* authentication information, which may be {@code null}
*
* @throws IllegalStateException if the provider requires configuration
* and {@link configure} has not been called
* @throws SecurityException if the caller does not pass a
* security check for
* {@code SecurityPermission("authProvider.name")},
* where {@code name} is the value returned by
* this provider's {@code getName} method
*/
public abstract void setCallbackHandler(CallbackHandler handler);
}

View file

@ -0,0 +1,548 @@
/*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamField;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.concurrent.ConcurrentHashMap;
/**
* The BasicPermission class extends the Permission class, and
* can be used as the base class for permissions that want to
* follow the same naming convention as BasicPermission.
* <P>
* The name for a BasicPermission is the name of the given permission
* (for example, "exit",
* "setFactory", "print.queueJob", etc). The naming
* convention follows the hierarchical property naming convention.
* An asterisk may appear by itself, or if immediately preceded by a "."
* may appear at the end of the name, to signify a wildcard match.
* For example, "*" and "java.*" signify a wildcard match, while "*java", "a*b",
* and "java*" do not.
* <P>
* The action string (inherited from Permission) is unused.
* Thus, BasicPermission is commonly used as the base class for
* "named" permissions
* (ones that contain a name but no actions list; you either have the
* named permission or you don't.)
* Subclasses may implement actions on top of BasicPermission,
* if desired.
*
* @see java.security.Permission
* @see java.security.Permissions
* @see java.security.PermissionCollection
* @see java.lang.SecurityManager
*
* @author Marianne Mueller
* @author Roland Schemers
* @since 1.2
*/
public abstract class BasicPermission extends Permission
implements java.io.Serializable
{
private static final long serialVersionUID = 6279438298436773498L;
// does this permission have a wildcard at the end?
private transient boolean wildcard;
// the name without the wildcard on the end
private transient String path;
// is this permission the old-style exitVM permission (pre JDK 1.6)?
private transient boolean exitVM;
/**
* initialize a BasicPermission object. Common to all constructors.
*/
private void init(String name) {
if (name == null)
throw new NullPointerException("name can't be null");
int len = name.length();
if (len == 0) {
throw new IllegalArgumentException("name can't be empty");
}
char last = name.charAt(len - 1);
// Is wildcard or ends with ".*"?
if (last == '*' && (len == 1 || name.charAt(len - 2) == '.')) {
wildcard = true;
if (len == 1) {
path = "";
} else {
path = name.substring(0, len - 1);
}
} else {
if (name.equals("exitVM")) {
wildcard = true;
path = "exitVM.";
exitVM = true;
} else {
path = name;
}
}
}
/**
* Creates a new BasicPermission with the specified name.
* Name is the symbolic name of the permission, such as
* "setFactory",
* "print.queueJob", or "topLevelWindow", etc.
*
* @param name the name of the BasicPermission.
*
* @throws NullPointerException if {@code name} is {@code null}.
* @throws IllegalArgumentException if {@code name} is empty.
*/
public BasicPermission(String name) {
super(name);
init(name);
}
/**
* Creates a new BasicPermission object with the specified name.
* The name is the symbolic name of the BasicPermission, and the
* actions String is currently unused.
*
* @param name the name of the BasicPermission.
* @param actions ignored.
*
* @throws NullPointerException if {@code name} is {@code null}.
* @throws IllegalArgumentException if {@code name} is empty.
*/
public BasicPermission(String name, String actions) {
super(name);
init(name);
}
/**
* Checks if the specified permission is "implied" by
* this object.
* <P>
* More specifically, this method returns true if:
* <ul>
* <li> {@code p}'s class is the same as this object's class, and
* <li> {@code p}'s name equals or (in the case of wildcards)
* is implied by this object's
* name. For example, "a.b.*" implies "a.b.c".
* </ul>
*
* @param p the permission to check against.
*
* @return true if the passed permission is equal to or
* implied by this permission, false otherwise.
*/
@Override
public boolean implies(Permission p) {
if ((p == null) || (p.getClass() != getClass()))
return false;
BasicPermission that = (BasicPermission) p;
if (this.wildcard) {
if (that.wildcard) {
// one wildcard can imply another
return that.path.startsWith(path);
} else {
// make sure ap.path is longer so a.b.* doesn't imply a.b
return (that.path.length() > this.path.length()) &&
that.path.startsWith(this.path);
}
} else {
if (that.wildcard) {
// a non-wildcard can't imply a wildcard
return false;
}
else {
return this.path.equals(that.path);
}
}
}
/**
* Checks two BasicPermission objects for equality.
* Checks that {@code obj}'s class is the same as this object's class
* and has the same name as this object.
*
* @param obj the object we are testing for equality with this object.
* @return true if {@code obj}'s class is the same as this object's class
* and has the same name as this BasicPermission object, false otherwise.
*/
@Override
public boolean equals(Object obj) {
if (obj == this)
return true;
if ((obj == null) || (obj.getClass() != getClass()))
return false;
BasicPermission bp = (BasicPermission) obj;
return getName().equals(bp.getName());
}
/**
* Returns the hash code value for this object.
* The hash code used is the hash code of the name, that is,
* {@code getName().hashCode()}, where {@code getName} is
* from the Permission superclass.
*
* @return a hash code value for this object.
*/
@Override
public int hashCode() {
return this.getName().hashCode();
}
/**
* Returns the canonical string representation of the actions,
* which currently is the empty string "", since there are no actions for
* a BasicPermission.
*
* @return the empty string "".
*/
@Override
public String getActions() {
return "";
}
/**
* Returns a new PermissionCollection object for storing BasicPermission
* objects.
*
* <p>BasicPermission objects must be stored in a manner that allows them
* to be inserted in any order, but that also enables the
* PermissionCollection {@code implies} method
* to be implemented in an efficient (and consistent) manner.
*
* @return a new PermissionCollection object suitable for
* storing BasicPermissions.
*/
@Override
public PermissionCollection newPermissionCollection() {
return new BasicPermissionCollection(this.getClass());
}
/**
* readObject is called to restore the state of the BasicPermission from
* a stream.
*/
private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException
{
s.defaultReadObject();
// init is called to initialize the rest of the values.
init(getName());
}
/**
* Returns the canonical name of this BasicPermission.
* All internal invocations of getName should invoke this method, so
* that the pre-JDK 1.6 "exitVM" and current "exitVM.*" permission are
* equivalent in equals/hashCode methods.
*
* @return the canonical name of this BasicPermission.
*/
final String getCanonicalName() {
return exitVM ? "exitVM.*" : getName();
}
}
/**
* A BasicPermissionCollection stores a collection
* of BasicPermission permissions. BasicPermission objects
* must be stored in a manner that allows them to be inserted in any
* order, but enable the implies function to evaluate the implies
* method in an efficient (and consistent) manner.
*
* A BasicPermissionCollection handles comparing a permission like "a.b.c.d.e"
* with a Permission such as "a.b.*", or "*".
*
* @see java.security.Permission
* @see java.security.Permissions
*
*
* @author Roland Schemers
*
* @serial include
*/
final class BasicPermissionCollection
extends PermissionCollection
implements java.io.Serializable
{
private static final long serialVersionUID = 739301742472979399L;
/**
* Key is name, value is permission. All permission objects in
* collection must be of the same type.
* Not serialized; see serialization section at end of class.
*/
private transient ConcurrentHashMap<String, Permission> perms;
/**
* This is set to {@code true} if this BasicPermissionCollection
* contains a BasicPermission with '*' as its permission name.
*
* @see #serialPersistentFields
*/
private boolean all_allowed;
/**
* The class to which all BasicPermissions in this
* BasicPermissionCollection belong.
*
* @see #serialPersistentFields
*/
private Class<?> permClass;
/**
* Create an empty BasicPermissionCollection object.
*
*/
public BasicPermissionCollection(Class<?> clazz) {
perms = new ConcurrentHashMap<>(11);
all_allowed = false;
permClass = clazz;
}
/**
* Adds a permission to the BasicPermissions. The key for the hash is
* permission.path.
*
* @param permission the Permission object to add.
*
* @exception IllegalArgumentException - if the permission is not a
* BasicPermission, or if
* the permission is not of the
* same Class as the other
* permissions in this collection.
*
* @exception SecurityException - if this BasicPermissionCollection object
* has been marked readonly
*/
@Override
public void add(Permission permission) {
if (! (permission instanceof BasicPermission))
throw new IllegalArgumentException("invalid permission: "+
permission);
if (isReadOnly())
throw new SecurityException("attempt to add a Permission to a readonly PermissionCollection");
BasicPermission bp = (BasicPermission) permission;
// make sure we only add new BasicPermissions of the same class
// Also check null for compatibility with deserialized form from
// previous versions.
if (permClass == null) {
// adding first permission
permClass = bp.getClass();
} else {
if (bp.getClass() != permClass)
throw new IllegalArgumentException("invalid permission: " +
permission);
}
String canonName = bp.getCanonicalName();
perms.put(canonName, permission);
// No sync on all_allowed; staleness OK
if (!all_allowed) {
if (canonName.equals("*"))
all_allowed = true;
}
}
/**
* Check and see if this set of permissions implies the permissions
* expressed in "permission".
*
* @param permission the Permission object to compare
*
* @return true if "permission" is a proper subset of a permission in
* the set, false if not.
*/
@Override
public boolean implies(Permission permission) {
if (! (permission instanceof BasicPermission))
return false;
BasicPermission bp = (BasicPermission) permission;
// random subclasses of BasicPermission do not imply each other
if (bp.getClass() != permClass)
return false;
// short circuit if the "*" Permission was added
if (all_allowed)
return true;
// strategy:
// Check for full match first. Then work our way up the
// path looking for matches on a.b..*
String path = bp.getCanonicalName();
//System.out.println("check "+path);
Permission x = perms.get(path);
if (x != null) {
// we have a direct hit!
return x.implies(permission);
}
// work our way up the tree...
int last, offset;
offset = path.length()-1;
while ((last = path.lastIndexOf('.', offset)) != -1) {
path = path.substring(0, last+1) + "*";
//System.out.println("check "+path);
x = perms.get(path);
if (x != null) {
return x.implies(permission);
}
offset = last -1;
}
// we don't have to check for "*" as it was already checked
// at the top (all_allowed), so we just return false
return false;
}
/**
* Returns an enumeration of all the BasicPermission objects in the
* container.
*
* @return an enumeration of all the BasicPermission objects.
*/
@Override
public Enumeration<Permission> elements() {
return perms.elements();
}
// Need to maintain serialization interoperability with earlier releases,
// which had the serializable field:
//
// @serial the Hashtable is indexed by the BasicPermission name
//
// private Hashtable permissions;
/**
* @serialField permissions java.util.Hashtable
* The BasicPermissions in this BasicPermissionCollection.
* All BasicPermissions in the collection must belong to the same class.
* The Hashtable is indexed by the BasicPermission name; the value
* of the Hashtable entry is the permission.
* @serialField all_allowed boolean
* This is set to {@code true} if this BasicPermissionCollection
* contains a BasicPermission with '*' as its permission name.
* @serialField permClass java.lang.Class
* The class to which all BasicPermissions in this
* BasicPermissionCollection belongs.
*/
private static final ObjectStreamField[] serialPersistentFields = {
new ObjectStreamField("permissions", Hashtable.class),
new ObjectStreamField("all_allowed", Boolean.TYPE),
new ObjectStreamField("permClass", Class.class),
};
/**
* @serialData Default fields.
*/
/*
* Writes the contents of the perms field out as a Hashtable for
* serialization compatibility with earlier releases. all_allowed
* and permClass unchanged.
*/
private void writeObject(ObjectOutputStream out) throws IOException {
// Don't call out.defaultWriteObject()
// Copy perms into a Hashtable
Hashtable<String, Permission> permissions =
new Hashtable<>(perms.size()*2);
permissions.putAll(perms);
// Write out serializable fields
ObjectOutputStream.PutField pfields = out.putFields();
pfields.put("all_allowed", all_allowed);
pfields.put("permissions", permissions);
pfields.put("permClass", permClass);
out.writeFields();
}
/**
* readObject is called to restore the state of the
* BasicPermissionCollection from a stream.
*/
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException
{
// Don't call defaultReadObject()
// Read in serialized fields
ObjectInputStream.GetField gfields = in.readFields();
// Get permissions
// writeObject writes a Hashtable<String, Permission> for the
// permissions key, so this cast is safe, unless the data is corrupt.
@SuppressWarnings("unchecked")
Hashtable<String, Permission> permissions =
(Hashtable<String, Permission>)gfields.get("permissions", null);
perms = new ConcurrentHashMap<>(permissions.size()*2);
perms.putAll(permissions);
// Get all_allowed
all_allowed = gfields.get("all_allowed", false);
// Get permClass
permClass = (Class<?>) gfields.get("permClass", null);
if (permClass == null) {
// set permClass
Enumeration<Permission> e = permissions.elements();
if (e.hasMoreElements()) {
Permission p = e.nextElement();
permClass = p.getClass();
}
}
}
}

View file

@ -0,0 +1,157 @@
/*
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
import java.io.*;
import java.util.Date;
/**
* <p>This is an interface of abstract methods for managing a
* variety of identity certificates.
* An identity certificate is a guarantee by a principal that
* a public key is that of another principal. (A principal represents
* an entity such as an individual user, a group, or a corporation.)
*
* <p>In particular, this interface is intended to be a common
* abstraction for constructs that have different formats but
* important common uses. For example, different types of
* certificates, such as X.509 certificates and PGP certificates,
* share general certificate functionality (the need to encode and
* decode certificates) and some types of information, such as a
* public key, the principal whose key it is, and the guarantor
* guaranteeing that the public key is that of the specified
* principal. So an implementation of X.509 certificates and an
* implementation of PGP certificates can both utilize the Certificate
* interface, even though their formats and additional types and
* amounts of information stored are different.
*
* <p><b>Important</b>: This interface is useful for cataloging and
* grouping objects sharing certain common uses. It does not have any
* semantics of its own. In particular, a Certificate object does not
* make any statement as to the <i>validity</i> of the binding. It is
* the duty of the application implementing this interface to verify
* the certificate and satisfy itself of its validity.
*
* @author Benjamin Renaud
* @since 1.1
* @deprecated A new certificate handling package is created in the Java platform.
* This Certificate interface is entirely deprecated and
* is here to allow for a smooth transition to the new
* package.
* @see java.security.cert.Certificate
*/
@Deprecated(since="1.2")
public interface Certificate {
/**
* Returns the guarantor of the certificate, that is, the principal
* guaranteeing that the public key associated with this certificate
* is that of the principal associated with this certificate. For X.509
* certificates, the guarantor will typically be a Certificate Authority
* (such as the United States Postal Service or Verisign, Inc.).
*
* @return the guarantor which guaranteed the principal-key
* binding.
*/
public abstract Principal getGuarantor();
/**
* Returns the principal of the principal-key pair being guaranteed by
* the guarantor.
*
* @return the principal to which this certificate is bound.
*/
public abstract Principal getPrincipal();
/**
* Returns the key of the principal-key pair being guaranteed by
* the guarantor.
*
* @return the public key that this certificate certifies belongs
* to a particular principal.
*/
public abstract PublicKey getPublicKey();
/**
* Encodes the certificate to an output stream in a format that can
* be decoded by the {@code decode} method.
*
* @param stream the output stream to which to encode the
* certificate.
*
* @exception KeyException if the certificate is not
* properly initialized, or data is missing, etc.
*
* @exception IOException if a stream exception occurs while
* trying to output the encoded certificate to the output stream.
*
* @see #decode
* @see #getFormat
*/
public abstract void encode(OutputStream stream)
throws KeyException, IOException;
/**
* Decodes a certificate from an input stream. The format should be
* that returned by {@code getFormat} and produced by
* {@code encode}.
*
* @param stream the input stream from which to fetch the data
* being decoded.
*
* @exception KeyException if the certificate is not properly initialized,
* or data is missing, etc.
*
* @exception IOException if an exception occurs while trying to input
* the encoded certificate from the input stream.
*
* @see #encode
* @see #getFormat
*/
public abstract void decode(InputStream stream)
throws KeyException, IOException;
/**
* Returns the name of the coding format. This is used as a hint to find
* an appropriate parser. It could be "X.509", "PGP", etc. This is
* the format produced and understood by the {@code encode}
* and {@code decode} methods.
*
* @return the name of the coding format.
*/
public abstract String getFormat();
/**
* Returns a string that represents the contents of the certificate.
*
* @param detailed whether or not to give detailed information
* about the certificate
*
* @return a string representing the contents of the certificate
*/
public String toString(boolean detailed);
}

View file

@ -0,0 +1,173 @@
/*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
import java.io.*;
import java.security.cert.CertPath;
/**
* This class encapsulates information about a code signer.
* It is immutable.
*
* @since 1.5
* @author Vincent Ryan
*/
public final class CodeSigner implements Serializable {
private static final long serialVersionUID = 6819288105193937581L;
/**
* The signer's certificate path.
*
* @serial
*/
private CertPath signerCertPath;
/*
* The signature timestamp.
*
* @serial
*/
private Timestamp timestamp;
/*
* Hash code for this code signer.
*/
private transient int myhash = -1;
/**
* Constructs a CodeSigner object.
*
* @param signerCertPath The signer's certificate path.
* It must not be {@code null}.
* @param timestamp A signature timestamp.
* If {@code null} then no timestamp was generated
* for the signature.
* @throws NullPointerException if {@code signerCertPath} is
* {@code null}.
*/
public CodeSigner(CertPath signerCertPath, Timestamp timestamp) {
if (signerCertPath == null) {
throw new NullPointerException();
}
this.signerCertPath = signerCertPath;
this.timestamp = timestamp;
}
/**
* Returns the signer's certificate path.
*
* @return A certificate path.
*/
public CertPath getSignerCertPath() {
return signerCertPath;
}
/**
* Returns the signature timestamp.
*
* @return The timestamp or {@code null} if none is present.
*/
public Timestamp getTimestamp() {
return timestamp;
}
/**
* Returns the hash code value for this code signer.
* The hash code is generated using the signer's certificate path and the
* timestamp, if present.
*
* @return a hash code value for this code signer.
*/
public int hashCode() {
if (myhash == -1) {
if (timestamp == null) {
myhash = signerCertPath.hashCode();
} else {
myhash = signerCertPath.hashCode() + timestamp.hashCode();
}
}
return myhash;
}
/**
* Tests for equality between the specified object and this
* code signer. Two code signers are considered equal if their
* signer certificate paths are equal and if their timestamps are equal,
* if present in both.
*
* @param obj the object to test for equality with this object.
*
* @return true if the objects are considered equal, false otherwise.
*/
public boolean equals(Object obj) {
if (obj == null || (!(obj instanceof CodeSigner))) {
return false;
}
CodeSigner that = (CodeSigner)obj;
if (this == that) {
return true;
}
Timestamp thatTimestamp = that.getTimestamp();
if (timestamp == null) {
if (thatTimestamp != null) {
return false;
}
} else {
if (thatTimestamp == null ||
(! timestamp.equals(thatTimestamp))) {
return false;
}
}
return signerCertPath.equals(that.getSignerCertPath());
}
/**
* Returns a string describing this code signer.
*
* @return A string comprising the signer's certificate and a timestamp,
* if present.
*/
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("(");
sb.append("Signer: " + signerCertPath.getCertificates().get(0));
if (timestamp != null) {
sb.append("timestamp: " + timestamp);
}
sb.append(")");
return sb.toString();
}
// Explicitly reset hash code value to -1
private void readObject(ObjectInputStream ois)
throws IOException, ClassNotFoundException {
ois.defaultReadObject();
myhash = -1;
}
}

View file

@ -0,0 +1,679 @@
/*
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
import java.net.URL;
import java.net.SocketPermission;
import java.util.ArrayList;
import java.util.List;
import java.util.Hashtable;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.cert.*;
import sun.net.util.URLUtil;
/**
*
* <p>This class extends the concept of a codebase to
* encapsulate not only the location (URL) but also the certificate chains
* that were used to verify signed code originating from that location.
*
* @author Li Gong
* @author Roland Schemers
* @since 1.2
*/
public class CodeSource implements java.io.Serializable {
private static final long serialVersionUID = 4977541819976013951L;
/**
* The code location.
*
* @serial
*/
private URL location;
/*
* The code signers.
*/
private transient CodeSigner[] signers = null;
/*
* The code signers. Certificate chains are concatenated.
*/
private transient java.security.cert.Certificate[] certs = null;
// cached SocketPermission used for matchLocation
private transient SocketPermission sp;
// for generating cert paths
private transient CertificateFactory factory = null;
/**
* A String form of the URL for use as a key in HashMaps/Sets. The String
* form should be behave in the same manner as the URL when compared for
* equality in a HashMap/Set, except that no nameservice lookup is done
* on the hostname (only string comparison), and the fragment is not
* considered.
*/
private transient String locationNoFragString;
/**
* Constructs a CodeSource and associates it with the specified
* location and set of certificates.
*
* @param url the location (URL). It may be {@code null}.
* @param certs the certificate(s). It may be {@code null}. The contents
* of the array are copied to protect against subsequent modification.
*/
public CodeSource(URL url, java.security.cert.Certificate[] certs) {
this.location = url;
if (url != null) {
this.locationNoFragString = URLUtil.urlNoFragString(url);
}
// Copy the supplied certs
if (certs != null) {
this.certs = certs.clone();
}
}
/**
* Constructs a CodeSource and associates it with the specified
* location and set of code signers.
*
* @param url the location (URL). It may be {@code null}.
* @param signers the code signers. It may be {@code null}. The contents
* of the array are copied to protect against subsequent modification.
*
* @since 1.5
*/
public CodeSource(URL url, CodeSigner[] signers) {
this.location = url;
if (url != null) {
this.locationNoFragString = URLUtil.urlNoFragString(url);
}
// Copy the supplied signers
if (signers != null) {
this.signers = signers.clone();
}
}
/**
* Returns the hash code value for this object.
*
* @return a hash code value for this object.
*/
@Override
public int hashCode() {
if (location != null)
return location.hashCode();
else
return 0;
}
/**
* Tests for equality between the specified object and this
* object. Two CodeSource objects are considered equal if their
* locations are of identical value and if their signer certificate
* chains are of identical value. It is not required that
* the certificate chains be in the same order.
*
* @param obj the object to test for equality with this object.
*
* @return true if the objects are considered equal, false otherwise.
*/
@Override
public boolean equals(Object obj) {
if (obj == this)
return true;
// objects types must be equal
if (!(obj instanceof CodeSource))
return false;
CodeSource cs = (CodeSource) obj;
// URLs must match
if (location == null) {
// if location is null, then cs.location must be null as well
if (cs.location != null) return false;
} else {
// if location is not null, then it must equal cs.location
if (!location.equals(cs.location)) return false;
}
// certs must match
return matchCerts(cs, true);
}
/**
* Returns the location associated with this CodeSource.
*
* @return the location (URL), or {@code null} if no URL was supplied
* during construction.
*/
public final URL getLocation() {
/* since URL is practically immutable, returning itself is not
a security problem */
return this.location;
}
/**
* Returns a String form of the URL for use as a key in HashMaps/Sets.
*/
String getLocationNoFragString() {
return locationNoFragString;
}
/**
* Returns the certificates associated with this CodeSource.
* <p>
* If this CodeSource object was created using the
* {@link #CodeSource(URL url, CodeSigner[] signers)}
* constructor then its certificate chains are extracted and used to
* create an array of Certificate objects. Each signer certificate is
* followed by its supporting certificate chain (which may be empty).
* Each signer certificate and its supporting certificate chain is ordered
* bottom-to-top (i.e., with the signer certificate first and the (root)
* certificate authority last).
*
* @return a copy of the certificate array, or {@code null} if there
* is none.
*/
public final java.security.cert.Certificate[] getCertificates() {
if (certs != null) {
return certs.clone();
} else if (signers != null) {
// Convert the code signers to certs
ArrayList<java.security.cert.Certificate> certChains =
new ArrayList<>();
for (int i = 0; i < signers.length; i++) {
certChains.addAll(
signers[i].getSignerCertPath().getCertificates());
}
certs = certChains.toArray(
new java.security.cert.Certificate[certChains.size()]);
return certs.clone();
} else {
return null;
}
}
/**
* Returns the code signers associated with this CodeSource.
* <p>
* If this CodeSource object was created using the
* {@link #CodeSource(URL url, java.security.cert.Certificate[] certs)}
* constructor then its certificate chains are extracted and used to
* create an array of CodeSigner objects. Note that only X.509 certificates
* are examined - all other certificate types are ignored.
*
* @return a copy of the code signer array, or {@code null} if there
* is none.
*
* @since 1.5
*/
public final CodeSigner[] getCodeSigners() {
if (signers != null) {
return signers.clone();
} else if (certs != null) {
// Convert the certs to code signers
signers = convertCertArrayToSignerArray(certs);
return signers.clone();
} else {
return null;
}
}
/**
* Returns true if this CodeSource object "implies" the specified CodeSource.
* <p>
* More specifically, this method makes the following checks.
* If any fail, it returns false. If they all succeed, it returns true.
* <ul>
* <li> <i>codesource</i> must not be null.
* <li> If this object's certificates are not null, then all
* of this object's certificates must be present in <i>codesource</i>'s
* certificates.
* <li> If this object's location (getLocation()) is not null, then the
* following checks are made against this object's location and
* <i>codesource</i>'s:
* <ul>
* <li> <i>codesource</i>'s location must not be null.
*
* <li> If this object's location
* equals <i>codesource</i>'s location, then return true.
*
* <li> This object's protocol (getLocation().getProtocol()) must be
* equal to <i>codesource</i>'s protocol, ignoring case.
*
* <li> If this object's host (getLocation().getHost()) is not null,
* then the SocketPermission
* constructed with this object's host must imply the
* SocketPermission constructed with <i>codesource</i>'s host.
*
* <li> If this object's port (getLocation().getPort()) is not
* equal to -1 (that is, if a port is specified), it must equal
* <i>codesource</i>'s port or default port
* (codesource.getLocation().getDefaultPort()).
*
* <li> If this object's file (getLocation().getFile()) doesn't equal
* <i>codesource</i>'s file, then the following checks are made:
* If this object's file ends with "/-",
* then <i>codesource</i>'s file must start with this object's
* file (exclusive the trailing "-").
* If this object's file ends with a "/*",
* then <i>codesource</i>'s file must start with this object's
* file and must not have any further "/" separators.
* If this object's file doesn't end with a "/",
* then <i>codesource</i>'s file must match this object's
* file with a '/' appended.
*
* <li> If this object's reference (getLocation().getRef()) is
* not null, it must equal <i>codesource</i>'s reference.
*
* </ul>
* </ul>
* <p>
* For example, the codesource objects with the following locations
* and null certificates all imply
* the codesource with the location "http://java.sun.com/classes/foo.jar"
* and null certificates:
* <pre>
* http:
* http://*.sun.com/classes/*
* http://java.sun.com/classes/-
* http://java.sun.com/classes/foo.jar
* </pre>
*
* Note that if this CodeSource has a null location and a null
* certificate chain, then it implies every other CodeSource.
*
* @param codesource CodeSource to compare against.
*
* @return true if the specified codesource is implied by this codesource,
* false if not.
*/
public boolean implies(CodeSource codesource)
{
if (codesource == null)
return false;
return matchCerts(codesource, false) && matchLocation(codesource);
}
/**
* Returns true if all the certs in this
* CodeSource are also in <i>that</i>.
*
* @param that the CodeSource to check against.
* @param strict if true then a strict equality match is performed.
* Otherwise a subset match is performed.
*/
boolean matchCerts(CodeSource that, boolean strict)
{
boolean match;
// match any key
if (certs == null && signers == null) {
if (strict) {
return (that.certs == null && that.signers == null);
} else {
return true;
}
// both have signers
} else if (signers != null && that.signers != null) {
if (strict && signers.length != that.signers.length) {
return false;
}
for (int i = 0; i < signers.length; i++) {
match = false;
for (int j = 0; j < that.signers.length; j++) {
if (signers[i].equals(that.signers[j])) {
match = true;
break;
}
}
if (!match) return false;
}
return true;
// both have certs
} else if (certs != null && that.certs != null) {
if (strict && certs.length != that.certs.length) {
return false;
}
for (int i = 0; i < certs.length; i++) {
match = false;
for (int j = 0; j < that.certs.length; j++) {
if (certs[i].equals(that.certs[j])) {
match = true;
break;
}
}
if (!match) return false;
}
return true;
}
return false;
}
/**
* Returns true if two CodeSource's have the "same" location.
*
* @param that CodeSource to compare against
*/
private boolean matchLocation(CodeSource that) {
if (location == null)
return true;
if ((that == null) || (that.location == null))
return false;
if (location.equals(that.location))
return true;
if (!location.getProtocol().equalsIgnoreCase(that.location.getProtocol()))
return false;
int thisPort = location.getPort();
if (thisPort != -1) {
int thatPort = that.location.getPort();
int port = thatPort != -1 ? thatPort
: that.location.getDefaultPort();
if (thisPort != port)
return false;
}
if (location.getFile().endsWith("/-")) {
// Matches the directory and (recursively) all files
// and subdirectories contained in that directory.
// For example, "/a/b/-" implies anything that starts with
// "/a/b/"
String thisPath = location.getFile().substring(0,
location.getFile().length()-1);
if (!that.location.getFile().startsWith(thisPath))
return false;
} else if (location.getFile().endsWith("/*")) {
// Matches the directory and all the files contained in that
// directory.
// For example, "/a/b/*" implies anything that starts with
// "/a/b/" but has no further slashes
int last = that.location.getFile().lastIndexOf('/');
if (last == -1)
return false;
String thisPath = location.getFile().substring(0,
location.getFile().length()-1);
String thatPath = that.location.getFile().substring(0, last+1);
if (!thatPath.equals(thisPath))
return false;
} else {
// Exact matches only.
// For example, "/a/b" and "/a/b/" both imply "/a/b/"
if ((!that.location.getFile().equals(location.getFile()))
&& (!that.location.getFile().equals(location.getFile()+"/"))) {
return false;
}
}
if (location.getRef() != null
&& !location.getRef().equals(that.location.getRef())) {
return false;
}
String thisHost = location.getHost();
String thatHost = that.location.getHost();
if (thisHost != null) {
if (("".equals(thisHost) || "localhost".equals(thisHost)) &&
("".equals(thatHost) || "localhost".equals(thatHost))) {
// ok
} else if (!thisHost.equals(thatHost)) {
if (thatHost == null) {
return false;
}
if (this.sp == null) {
this.sp = new SocketPermission(thisHost, "resolve");
}
if (that.sp == null) {
that.sp = new SocketPermission(thatHost, "resolve");
}
if (!this.sp.implies(that.sp)) {
return false;
}
}
}
// everything matches
return true;
}
/**
* Returns a string describing this CodeSource, telling its
* URL and certificates.
*
* @return information about this CodeSource.
*/
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("(");
sb.append(this.location);
if (this.certs != null && this.certs.length > 0) {
for (int i = 0; i < this.certs.length; i++) {
sb.append( " " + this.certs[i]);
}
} else if (this.signers != null && this.signers.length > 0) {
for (int i = 0; i < this.signers.length; i++) {
sb.append( " " + this.signers[i]);
}
} else {
sb.append(" <no signer certificates>");
}
sb.append(")");
return sb.toString();
}
/**
* Writes this object out to a stream (i.e., serializes it).
*
* @serialData An initial {@code URL} is followed by an
* {@code int} indicating the number of certificates to follow
* (a value of "zero" denotes that there are no certificates associated
* with this object).
* Each certificate is written out starting with a {@code String}
* denoting the certificate type, followed by an
* {@code int} specifying the length of the certificate encoding,
* followed by the certificate encoding itself which is written out as an
* array of bytes. Finally, if any code signers are present then the array
* of code signers is serialized and written out too.
*/
private void writeObject(java.io.ObjectOutputStream oos)
throws IOException
{
oos.defaultWriteObject(); // location
// Serialize the array of certs
if (certs == null || certs.length == 0) {
oos.writeInt(0);
} else {
// write out the total number of certs
oos.writeInt(certs.length);
// write out each cert, including its type
for (int i = 0; i < certs.length; i++) {
java.security.cert.Certificate cert = certs[i];
try {
oos.writeUTF(cert.getType());
byte[] encoded = cert.getEncoded();
oos.writeInt(encoded.length);
oos.write(encoded);
} catch (CertificateEncodingException cee) {
throw new IOException(cee.getMessage());
}
}
}
// Serialize the array of code signers (if any)
if (signers != null && signers.length > 0) {
oos.writeObject(signers);
}
}
/**
* Restores this object from a stream (i.e., deserializes it).
*/
private void readObject(java.io.ObjectInputStream ois)
throws IOException, ClassNotFoundException
{
CertificateFactory cf;
Hashtable<String, CertificateFactory> cfs = null;
List<java.security.cert.Certificate> certList = null;
ois.defaultReadObject(); // location
// process any new-style certs in the stream (if present)
int size = ois.readInt();
if (size > 0) {
// we know of 3 different cert types: X.509, PGP, SDSI, which
// could all be present in the stream at the same time
cfs = new Hashtable<>(3);
certList = new ArrayList<>(size > 20 ? 20 : size);
}
for (int i = 0; i < size; i++) {
// read the certificate type, and instantiate a certificate
// factory of that type (reuse existing factory if possible)
String certType = ois.readUTF();
if (cfs.containsKey(certType)) {
// reuse certificate factory
cf = cfs.get(certType);
} else {
// create new certificate factory
try {
cf = CertificateFactory.getInstance(certType);
} catch (CertificateException ce) {
throw new ClassNotFoundException
("Certificate factory for " + certType + " not found");
}
// store the certificate factory so we can reuse it later
cfs.put(certType, cf);
}
// parse the certificate
byte[] encoded = null;
try {
encoded = new byte[ois.readInt()];
} catch (OutOfMemoryError oome) {
throw new IOException("Certificate too big");
}
ois.readFully(encoded);
ByteArrayInputStream bais = new ByteArrayInputStream(encoded);
try {
certList.add(cf.generateCertificate(bais));
} catch (CertificateException ce) {
throw new IOException(ce.getMessage());
}
bais.close();
}
if (certList != null) {
this.certs = certList.toArray(
new java.security.cert.Certificate[size]);
}
// Deserialize array of code signers (if any)
try {
this.signers = ((CodeSigner[])ois.readObject()).clone();
} catch (IOException ioe) {
// no signers present
}
if (location != null) {
locationNoFragString = URLUtil.urlNoFragString(location);
}
}
/*
* Convert an array of certificates to an array of code signers.
* The array of certificates is a concatenation of certificate chains
* where the initial certificate in each chain is the end-entity cert.
*
* @return an array of code signers or null if none are generated.
*/
private CodeSigner[] convertCertArrayToSignerArray(
java.security.cert.Certificate[] certs) {
if (certs == null) {
return null;
}
try {
// Initialize certificate factory
if (factory == null) {
factory = CertificateFactory.getInstance("X.509");
}
// Iterate through all the certificates
int i = 0;
List<CodeSigner> signers = new ArrayList<>();
while (i < certs.length) {
List<java.security.cert.Certificate> certChain =
new ArrayList<>();
certChain.add(certs[i++]); // first cert is an end-entity cert
int j = i;
// Extract chain of certificates
// (loop while certs are not end-entity certs)
while (j < certs.length &&
certs[j] instanceof X509Certificate &&
((X509Certificate)certs[j]).getBasicConstraints() != -1) {
certChain.add(certs[j]);
j++;
}
i = j;
CertPath certPath = factory.generateCertPath(certChain);
signers.add(new CodeSigner(certPath, null));
}
if (signers.isEmpty()) {
return null;
} else {
return signers.toArray(new CodeSigner[signers.size()]);
}
} catch (CertificateException e) {
return null; //TODO - may be better to throw an ex. here
}
}
}

View file

@ -0,0 +1,83 @@
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
/**
* An enumeration of cryptographic primitives.
*
* @since 1.7
*/
public enum CryptoPrimitive {
/**
* Hash function
*/
MESSAGE_DIGEST,
/**
* Cryptographic random number generator
*/
SECURE_RANDOM,
/**
* Symmetric primitive: block cipher
*/
BLOCK_CIPHER,
/**
* Symmetric primitive: stream cipher
*/
STREAM_CIPHER,
/**
* Symmetric primitive: message authentication code
*/
MAC,
/**
* Symmetric primitive: key wrap
*/
KEY_WRAP,
/**
* Asymmetric primitive: public key encryption
*/
PUBLIC_KEY_ENCRYPTION,
/**
* Asymmetric primitive: signature scheme
*/
SIGNATURE,
/**
* Asymmetric primitive: key encapsulation mechanism
*/
KEY_ENCAPSULATION,
/**
* Asymmetric primitive: key agreement and key distribution
*/
KEY_AGREEMENT
}

View file

@ -0,0 +1,87 @@
/*
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
/**
* This is the generic Message Digest exception.
*
* @author Benjamin Renaud
* @since 1.1
*/
public class DigestException extends GeneralSecurityException {
private static final long serialVersionUID = 5821450303093652515L;
/**
* Constructs a DigestException with no detail message. (A
* detail message is a String that describes this particular
* exception.)
*/
public DigestException() {
super();
}
/**
* Constructs a DigestException with the specified detail
* message. (A detail message is a String that describes this
* particular exception.)
*
* @param msg the detail message.
*/
public DigestException(String msg) {
super(msg);
}
/**
* Creates a {@code DigestException} with the specified
* detail message and cause.
*
* @param message the detail message (which is saved for later retrieval
* by the {@link #getMessage()} method).
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is permitted,
* and indicates that the cause is nonexistent or unknown.)
* @since 1.5
*/
public DigestException(String message, Throwable cause) {
super(message, cause);
}
/**
* Creates a {@code DigestException} with the specified cause
* and a detail message of {@code (cause==null ? null : cause.toString())}
* (which typically contains the class and detail message of
* {@code cause}).
*
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is permitted,
* and indicates that the cause is nonexistent or unknown.)
* @since 1.5
*/
public DigestException(Throwable cause) {
super(cause);
}
}

View file

@ -0,0 +1,189 @@
/*
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
import java.io.IOException;
import java.io.EOFException;
import java.io.InputStream;
import java.io.FilterInputStream;
import java.io.PrintStream;
import java.io.ByteArrayInputStream;
/**
* A transparent stream that updates the associated message digest using
* the bits going through the stream.
*
* <p>To complete the message digest computation, call one of the
* {@code digest} methods on the associated message
* digest after your calls to one of this digest input stream's
* {@link #read() read} methods.
*
* <p>It is possible to turn this stream on or off (see
* {@link #on(boolean) on}). When it is on, a call to one of the
* {@code read} methods
* results in an update on the message digest. But when it is off,
* the message digest is not updated. The default is for the stream
* to be on.
*
* <p>Note that digest objects can compute only one digest (see
* {@link MessageDigest}),
* so that in order to compute intermediate digests, a caller should
* retain a handle onto the digest object, and clone it for each
* digest to be computed, leaving the original digest untouched.
*
* @see MessageDigest
*
* @see DigestOutputStream
*
* @author Benjamin Renaud
* @since 1.2
*/
public class DigestInputStream extends FilterInputStream {
/* NOTE: This should be made a generic UpdaterInputStream */
/* Are we on or off? */
private boolean on = true;
/**
* The message digest associated with this stream.
*/
protected MessageDigest digest;
/**
* Creates a digest input stream, using the specified input stream
* and message digest.
*
* @param stream the input stream.
*
* @param digest the message digest to associate with this stream.
*/
public DigestInputStream(InputStream stream, MessageDigest digest) {
super(stream);
setMessageDigest(digest);
}
/**
* Returns the message digest associated with this stream.
*
* @return the message digest associated with this stream.
* @see #setMessageDigest(java.security.MessageDigest)
*/
public MessageDigest getMessageDigest() {
return digest;
}
/**
* Associates the specified message digest with this stream.
*
* @param digest the message digest to be associated with this stream.
* @see #getMessageDigest()
*/
public void setMessageDigest(MessageDigest digest) {
this.digest = digest;
}
/**
* Reads a byte, and updates the message digest (if the digest
* function is on). That is, this method reads a byte from the
* input stream, blocking until the byte is actually read. If the
* digest function is on (see {@link #on(boolean) on}), this method
* will then call {@code update} on the message digest associated
* with this stream, passing it the byte read.
*
* @return the byte read.
*
* @exception IOException if an I/O error occurs.
*
* @see MessageDigest#update(byte)
*/
public int read() throws IOException {
int ch = in.read();
if (on && ch != -1) {
digest.update((byte)ch);
}
return ch;
}
/**
* Reads into a byte array, and updates the message digest (if the
* digest function is on). That is, this method reads up to
* {@code len} bytes from the input stream into the array
* {@code b}, starting at offset {@code off}. This method
* blocks until the data is actually
* read. If the digest function is on (see
* {@link #on(boolean) on}), this method will then call {@code update}
* on the message digest associated with this stream, passing it
* the data.
*
* @param b the array into which the data is read.
*
* @param off the starting offset into {@code b} of where the
* data should be placed.
*
* @param len the maximum number of bytes to be read from the input
* stream into b, starting at offset {@code off}.
*
* @return the actual number of bytes read. This is less than
* {@code len} if the end of the stream is reached prior to
* reading {@code len} bytes. -1 is returned if no bytes were
* read because the end of the stream had already been reached when
* the call was made.
*
* @exception IOException if an I/O error occurs.
*
* @see MessageDigest#update(byte[], int, int)
*/
public int read(byte[] b, int off, int len) throws IOException {
int result = in.read(b, off, len);
if (on && result != -1) {
digest.update(b, off, result);
}
return result;
}
/**
* Turns the digest function on or off. The default is on. When
* it is on, a call to one of the {@code read} methods results in an
* update on the message digest. But when it is off, the message
* digest is not updated.
*
* @param on true to turn the digest function on, false to turn
* it off.
*/
public void on(boolean on) {
this.on = on;
}
/**
* Prints a string representation of this digest input stream and
* its associated message digest object.
*/
public String toString() {
return "[Digest Input Stream] " + digest.toString();
}
}

View file

@ -0,0 +1,172 @@
/*
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
import java.io.IOException;
import java.io.EOFException;
import java.io.OutputStream;
import java.io.FilterOutputStream;
import java.io.PrintStream;
import java.io.ByteArrayOutputStream;
/**
* A transparent stream that updates the associated message digest using
* the bits going through the stream.
*
* <p>To complete the message digest computation, call one of the
* {@code digest} methods on the associated message
* digest after your calls to one of this digest output stream's
* {@link #write(int) write} methods.
*
* <p>It is possible to turn this stream on or off (see
* {@link #on(boolean) on}). When it is on, a call to one of the
* {@code write} methods results in
* an update on the message digest. But when it is off, the message
* digest is not updated. The default is for the stream to be on.
*
* @see MessageDigest
* @see DigestInputStream
*
* @author Benjamin Renaud
* @since 1.2
*/
public class DigestOutputStream extends FilterOutputStream {
private boolean on = true;
/**
* The message digest associated with this stream.
*/
protected MessageDigest digest;
/**
* Creates a digest output stream, using the specified output stream
* and message digest.
*
* @param stream the output stream.
*
* @param digest the message digest to associate with this stream.
*/
public DigestOutputStream(OutputStream stream, MessageDigest digest) {
super(stream);
setMessageDigest(digest);
}
/**
* Returns the message digest associated with this stream.
*
* @return the message digest associated with this stream.
* @see #setMessageDigest(java.security.MessageDigest)
*/
public MessageDigest getMessageDigest() {
return digest;
}
/**
* Associates the specified message digest with this stream.
*
* @param digest the message digest to be associated with this stream.
* @see #getMessageDigest()
*/
public void setMessageDigest(MessageDigest digest) {
this.digest = digest;
}
/**
* Updates the message digest (if the digest function is on) using
* the specified byte, and in any case writes the byte
* to the output stream. That is, if the digest function is on
* (see {@link #on(boolean) on}), this method calls
* {@code update} on the message digest associated with this
* stream, passing it the byte {@code b}. This method then
* writes the byte to the output stream, blocking until the byte
* is actually written.
*
* @param b the byte to be used for updating and writing to the
* output stream.
*
* @exception IOException if an I/O error occurs.
*
* @see MessageDigest#update(byte)
*/
public void write(int b) throws IOException {
out.write(b);
if (on) {
digest.update((byte)b);
}
}
/**
* Updates the message digest (if the digest function is on) using
* the specified subarray, and in any case writes the subarray to
* the output stream. That is, if the digest function is on (see
* {@link #on(boolean) on}), this method calls {@code update}
* on the message digest associated with this stream, passing it
* the subarray specifications. This method then writes the subarray
* bytes to the output stream, blocking until the bytes are actually
* written.
*
* @param b the array containing the subarray to be used for updating
* and writing to the output stream.
*
* @param off the offset into {@code b} of the first byte to
* be updated and written.
*
* @param len the number of bytes of data to be updated and written
* from {@code b}, starting at offset {@code off}.
*
* @exception IOException if an I/O error occurs.
*
* @see MessageDigest#update(byte[], int, int)
*/
public void write(byte[] b, int off, int len) throws IOException {
out.write(b, off, len);
if (on) {
digest.update(b, off, len);
}
}
/**
* Turns the digest function on or off. The default is on. When
* it is on, a call to one of the {@code write} methods results in an
* update on the message digest. But when it is off, the message
* digest is not updated.
*
* @param on true to turn the digest function on, false to turn it
* off.
*/
public void on(boolean on) {
this.on = on;
}
/**
* Prints a string representation of this digest output stream and
* its associated message digest object.
*/
public String toString() {
return "[Digest Output Stream] " + digest.toString();
}
}

View file

@ -0,0 +1,110 @@
/*
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
/**
* A {@code DomainCombiner} provides a means to dynamically
* update the ProtectionDomains associated with the current
* {@code AccessControlContext}.
*
* <p> A {@code DomainCombiner} is passed as a parameter to the
* appropriate constructor for {@code AccessControlContext}.
* The newly constructed context is then passed to the
* {@code AccessController.doPrivileged(..., context)} method
* to bind the provided context (and associated {@code DomainCombiner})
* with the current execution Thread. Subsequent calls to
* {@code AccessController.getContext} or
* {@code AccessController.checkPermission}
* cause the {@code DomainCombiner.combine} to get invoked.
*
* <p> The combine method takes two arguments. The first argument represents
* an array of ProtectionDomains from the current execution Thread,
* since the most recent call to {@code AccessController.doPrivileged}.
* If no call to doPrivileged was made, then the first argument will contain
* all the ProtectionDomains from the current execution Thread.
* The second argument represents an array of inherited ProtectionDomains,
* which may be {@code null}. ProtectionDomains may be inherited
* from a parent Thread, or from a privileged context. If no call to
* doPrivileged was made, then the second argument will contain the
* ProtectionDomains inherited from the parent Thread. If one or more calls
* to doPrivileged were made, and the most recent call was to
* doPrivileged(action, context), then the second argument will contain the
* ProtectionDomains from the privileged context. If the most recent call
* was to doPrivileged(action), then there is no privileged context,
* and the second argument will be {@code null}.
*
* <p> The {@code combine} method investigates the two input arrays
* of ProtectionDomains and returns a single array containing the updated
* ProtectionDomains. In the simplest case, the {@code combine}
* method merges the two stacks into one. In more complex cases,
* the {@code combine} method returns a modified
* stack of ProtectionDomains. The modification may have added new
* ProtectionDomains, removed certain ProtectionDomains, or simply
* updated existing ProtectionDomains. Re-ordering and other optimizations
* to the ProtectionDomains are also permitted. Typically the
* {@code combine} method bases its updates on the information
* encapsulated in the {@code DomainCombiner}.
*
* <p> After the {@code AccessController.getContext} method
* receives the combined stack of ProtectionDomains back from
* the {@code DomainCombiner}, it returns a new
* AccessControlContext that has both the combined ProtectionDomains
* as well as the {@code DomainCombiner}.
*
* @see AccessController
* @see AccessControlContext
* @since 1.3
*/
public interface DomainCombiner {
/**
* Modify or update the provided ProtectionDomains.
* ProtectionDomains may be added to or removed from the given
* ProtectionDomains. The ProtectionDomains may be re-ordered.
* Individual ProtectionDomains may be modified (with a new
* set of Permissions, for example).
*
* @param currentDomains the ProtectionDomains associated with the
* current execution Thread, up to the most recent
* privileged {@code ProtectionDomain}.
* The ProtectionDomains are listed in order of execution,
* with the most recently executing {@code ProtectionDomain}
* residing at the beginning of the array. This parameter may
* be {@code null} if the current execution Thread
* has no associated ProtectionDomains.
*
* @param assignedDomains an array of inherited ProtectionDomains.
* ProtectionDomains may be inherited from a parent Thread,
* or from a privileged {@code AccessControlContext}.
* This parameter may be {@code null}
* if there are no inherited ProtectionDomains.
*
* @return a new array consisting of the updated ProtectionDomains,
* or {@code null}.
*/
ProtectionDomain[] combine(ProtectionDomain[] currentDomains,
ProtectionDomain[] assignedDomains);
}

View file

@ -0,0 +1,171 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
import java.net.URI;
import java.util.*;
import static java.security.KeyStore.*;
/**
* Configuration data that specifies the keystores in a keystore domain.
* A keystore domain is a collection of keystores that are presented as a
* single logical keystore. The configuration data is used during
* {@code KeyStore}
* {@link KeyStore#load(KeyStore.LoadStoreParameter) load} and
* {@link KeyStore#store(KeyStore.LoadStoreParameter) store} operations.
* <p>
* The following syntax is supported for configuration data:
* <pre>{@code
* domain <domainName> [<property> ...] {
* keystore <keystoreName> [<property> ...] ;
* ...
* };
* ...
* }</pre>
* where {@code domainName} and {@code keystoreName} are identifiers
* and {@code property} is a key/value pairing. The key and value are
* separated by an 'equals' symbol and the value is enclosed in double
* quotes. A property value may be either a printable string or a binary
* string of colon-separated pairs of hexadecimal digits. Multi-valued
* properties are represented as a comma-separated list of values,
* enclosed in square brackets.
* See {@link Arrays#toString(java.lang.Object[])}.
* <p>
* To ensure that keystore entries are uniquely identified, each
* entry's alias is prefixed by its {@code keystoreName} followed
* by the entry name separator and each {@code keystoreName} must be
* unique within its domain. Entry name prefixes are omitted when
* storing a keystore.
* <p>
* Properties are context-sensitive: properties that apply to
* all the keystores in a domain are located in the domain clause,
* and properties that apply only to a specific keystore are located
* in that keystore's clause.
* Unless otherwise specified, a property in a keystore clause overrides
* a property of the same name in the domain clause. All property names
* are case-insensitive. The following properties are supported:
* <dl>
* <dt> {@code keystoreType="<type>"} </dt>
* <dd> The keystore type. </dd>
* <dt> {@code keystoreURI="<url>"} </dt>
* <dd> The keystore location. </dd>
* <dt> {@code keystoreProviderName="<name>"} </dt>
* <dd> The name of the keystore's JCE provider. </dd>
* <dt> {@code keystorePasswordEnv="<environment-variable>"} </dt>
* <dd> The environment variable that stores a keystore password.
* Alternatively, passwords may be supplied to the constructor
* method in a {@code Map<String, ProtectionParameter>}. </dd>
* <dt> {@code entryNameSeparator="<separator>"} </dt>
* <dd> The separator between a keystore name prefix and an entry name.
* When specified, it applies to all the entries in a domain.
* Its default value is a space. </dd>
* </dl>
* <p>
* For example, configuration data for a simple keystore domain
* comprising three keystores is shown below:
* <pre>
*
* domain app1 {
* keystore app1-truststore
* keystoreURI="file:///app1/etc/truststore.jks";
*
* keystore system-truststore
* keystoreURI="${java.home}/lib/security/cacerts";
*
* keystore app1-keystore
* keystoreType="PKCS12"
* keystoreURI="file:///app1/etc/keystore.p12";
* };
*
* </pre>
* @since 1.8
*/
public final class DomainLoadStoreParameter implements LoadStoreParameter {
private final URI configuration;
private final Map<String,ProtectionParameter> protectionParams;
/**
* Constructs a DomainLoadStoreParameter for a keystore domain with
* the parameters used to protect keystore data.
*
* @param configuration identifier for the domain configuration data.
* The name of the target domain should be specified in the
* {@code java.net.URI} fragment component when it is necessary
* to distinguish between several domain configurations at the
* same location.
*
* @param protectionParams the map from keystore name to the parameter
* used to protect keystore data.
* A {@code java.util.Collections.EMPTY_MAP} should be used
* when protection parameters are not required or when they have
* been specified by properties in the domain configuration data.
* It is cloned to prevent subsequent modification.
*
* @exception NullPointerException if {@code configuration} or
* {@code protectionParams} is {@code null}
*/
public DomainLoadStoreParameter(URI configuration,
Map<String,ProtectionParameter> protectionParams) {
if (configuration == null || protectionParams == null) {
throw new NullPointerException("invalid null input");
}
this.configuration = configuration;
this.protectionParams =
Collections.unmodifiableMap(new HashMap<>(protectionParams));
}
/**
* Gets the identifier for the domain configuration data.
*
* @return the identifier for the configuration data
*/
public URI getConfiguration() {
return configuration;
}
/**
* Gets the keystore protection parameters for keystores in this
* domain.
*
* @return an unmodifiable map of keystore names to protection
* parameters
*/
public Map<String,ProtectionParameter> getProtectionParams() {
return protectionParams;
}
/**
* Gets the keystore protection parameters for this domain.
* Keystore domains do not support a protection parameter.
*
* @return always returns {@code null}
*/
@Override
public KeyStore.ProtectionParameter getProtectionParameter() {
return null;
}
}

View file

@ -0,0 +1,556 @@
/*
* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
import java.util.Locale;
import java.util.Objects;
/**
* This class specifies the parameters used by a DRBG (Deterministic
* Random Bit Generator).
* <p>
* According to
* <a href="http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf">
* NIST Special Publication 800-90A Revision 1, Recommendation for Random
* Number Generation Using Deterministic Random Bit Generators</a> (800-90Ar1),
* <blockquote>
* A DRBG is based on a DRBG mechanism as specified in this Recommendation
* and includes a source of randomness. A DRBG mechanism uses an algorithm
* (i.e., a DRBG algorithm) that produces a sequence of bits from an initial
* value that is determined by a seed that is determined from the output of
* the randomness source."
* </blockquote>
* <p>
* The 800-90Ar1 specification allows for a variety of DRBG implementation
* choices, such as:
* <ul>
* <li> an entropy source,
* <li> a DRBG mechanism (for example, Hash_DRBG),
* <li> a DRBG algorithm (for example, SHA-256 for Hash_DRBG and AES-256
* for CTR_DRBG. Please note that it is not the algorithm used in
* {@link SecureRandom#getInstance}, which we will call a
* <em>SecureRandom algorithm</em> below),
* <li> optional features, including prediction resistance
* and reseeding supports,
* <li> highest security strength.
* </ul>
* <p>
* These choices are set in each implementation and are not directly
* managed by the {@code SecureRandom} API. Check your DRBG provider's
* documentation to find an appropriate implementation for the situation.
* <p>
* On the other hand, the 800-90Ar1 specification does have some configurable
* options, such as:
* <ul>
* <li> required security strength,
* <li> if prediction resistance is required,
* <li> personalization string and additional input.
* </ul>
* <p>
* A DRBG instance can be instantiated with parameters from an
* {@link DrbgParameters.Instantiation} object and other information
* (for example, the nonce, which is not managed by this API). This maps
* to the {@code Instantiate_function} defined in NIST SP 800-90Ar1.
* <p>
* A DRBG instance can be reseeded with parameters from a
* {@link DrbgParameters.Reseed} object. This maps to the
* {@code Reseed_function} defined in NIST SP 800-90Ar1. Calling
* {@link SecureRandom#reseed()} is equivalent to calling
* {@link SecureRandom#reseed(SecureRandomParameters)} with the effective
* instantiated prediction resistance flag (as returned by
* {@link SecureRandom#getParameters()}) with no additional input.
* <p>
* A DRBG instance generates data with additional parameters from a
* {@link DrbgParameters.NextBytes} object. This maps to the
* {@code Generate_function} defined in NIST SP 800-90Ar1. Calling
* {@link SecureRandom#nextBytes(byte[])} is equivalent to calling
* {@link SecureRandom#nextBytes(byte[], SecureRandomParameters)}
* with the effective instantiated strength and prediction resistance flag
* (as returned by {@link SecureRandom#getParameters()}) with no
* additional input.
* <p>
* A DRBG should be implemented as a subclass of {@link SecureRandomSpi}.
* It is recommended that the implementation contain the 1-arg
* {@linkplain SecureRandomSpi#SecureRandomSpi(SecureRandomParameters) constructor}
* that takes a {@code DrbgParameters.Instantiation} argument. If implemented
* this way, this implementation can be chosen by any
* {@code SecureRandom.getInstance()} method. If it is chosen by a
* {@code SecureRandom.getInstance()} with a {@link SecureRandomParameters}
* parameter, the parameter is passed into this constructor. If it is chosen
* by a {@code SecureRandom.getInstance()} without a
* {@code SecureRandomParameters} parameter, the constructor is called with
* a {@code null} argument and the implementation should choose its own
* parameters. Its {@link SecureRandom#getParameters()} must always return a
* non-null effective {@code DrbgParameters.Instantiation} object that reflects
* how the DRBG is actually instantiated. A caller can use this information
* to determine whether a {@code SecureRandom} object is a DRBG and what
* features it supports. Please note that the returned value does not
* necessarily equal to the {@code DrbgParameters.Instantiation} object passed
* into the {@code SecureRandom.getInstance()} call. For example,
* the requested capability can be {@link DrbgParameters.Capability#NONE}
* but the effective value can be {@link DrbgParameters.Capability#RESEED_ONLY}
* if the implementation supports reseeding. The implementation must implement
* the {@link SecureRandomSpi#engineNextBytes(byte[], SecureRandomParameters)}
* method which takes a {@code DrbgParameters.NextBytes} parameter. Unless
* the result of {@link SecureRandom#getParameters()} has its
* {@linkplain DrbgParameters.Instantiation#getCapability() capability} being
* {@link Capability#NONE NONE}, it must implement
* {@link SecureRandomSpi#engineReseed(SecureRandomParameters)} which takes
* a {@code DrbgParameters.Reseed} parameter.
* <p>
* On the other hand, if a DRBG implementation does not contain a constructor
* that has an {@code DrbgParameters.Instantiation} argument (not recommended),
* it can only be chosen by a {@code SecureRandom.getInstance()} without
* a {@code SecureRandomParameters} parameter, but will not be chosen if
* a {@code getInstance} method with a {@code SecureRandomParameters} parameter
* is called. If implemented this way, its {@link SecureRandom#getParameters()}
* must return {@code null}, and it does not need to implement either
* {@link SecureRandomSpi#engineNextBytes(byte[], SecureRandomParameters)}
* or {@link SecureRandomSpi#engineReseed(SecureRandomParameters)}.
* <p>
* A DRBG might reseed itself automatically if the seed period is bigger
* than the maximum seed life defined by the DRBG mechanism.
* <p>
* A DRBG implementation should support serialization and deserialization
* by retaining the configuration and effective parameters, but the internal
* state must not be serialized and the deserialized object must be
* reinstantiated.
* <p>
* Examples:
* <blockquote><pre>
* SecureRandom drbg;
* byte[] buffer = new byte[32];
*
* // Any DRBG is OK
* drbg = SecureRandom.getInstance("DRBG");
* drbg.nextBytes(buffer);
*
* SecureRandomParameters params = drbg.getParameters();
* if (params instanceof DrbgParameters.Instantiation) {
* DrbgParameters.Instantiation ins = (DrbgParameters.Instantiation) params;
* if (ins.getCapability().supportsReseeding()) {
* drbg.reseed();
* }
* }
*
* // The following call requests a weak DRBG instance. It is only
* // guaranteed to support 112 bits of security strength.
* drbg = SecureRandom.getInstance("DRBG",
* DrbgParameters.instantiation(112, NONE, null));
*
* // Both the next two calls will likely fail, because drbg could be
* // instantiated with a smaller strength with no prediction resistance
* // support.
* drbg.nextBytes(buffer,
* DrbgParameters.nextBytes(256, false, "more".getBytes()));
* drbg.nextBytes(buffer,
* DrbgParameters.nextBytes(112, true, "more".getBytes()));
*
* // The following call requests a strong DRBG instance, with a
* // personalization string. If it successfully returns an instance,
* // that instance is guaranteed to support 256 bits of security strength
* // with prediction resistance available.
* drbg = SecureRandom.getInstance("DRBG", DrbgParameters.instantiation(
* 256, PR_AND_RESEED, "hello".getBytes()));
*
* // Prediction resistance is not requested in this single call,
* // but an additional input is used.
* drbg.nextBytes(buffer,
* DrbgParameters.nextBytes(-1, false, "more".getBytes()));
*
* // Same for this call.
* drbg.reseed(DrbgParameters.reseed(false, "extra".getBytes()));</pre>
* </blockquote>
*
* @implSpec
* By convention, a provider should name its primary DRBG implementation
* with the <a href=
* "{@docRoot}/../specs/security/standard-names.html#securerandom-number-generation-algorithms">
* standard {@code SecureRandom} algorithm name</a> "DRBG".
*
* @implNote
* The following notes apply to the "DRBG" implementation in the SUN provider
* of the JDK reference implementation.
* <p>
* This implementation supports the Hash_DRBG and HMAC_DRBG mechanisms with
* DRBG algorithm SHA-224, SHA-512/224, SHA-256, SHA-512/256, SHA-384 and
* SHA-512, and CTR_DRBG (both using derivation function and not using
* derivation function) with DRBG algorithm AES-128, AES-192 and AES-256.
* <p>
* The mechanism name and DRBG algorithm name are determined by the
* {@linkplain Security#getProperty(String) security property}
* {@code securerandom.drbg.config}. The default choice is Hash_DRBG
* with SHA-256.
* <p>
* For each combination, the security strength can be requested from 112
* up to the highest strength it supports. Both reseeding and prediction
* resistance are supported.
* <p>
* Personalization string is supported through the
* {@link DrbgParameters.Instantiation} class and additional input is supported
* through the {@link DrbgParameters.NextBytes} and
* {@link DrbgParameters.Reseed} classes.
* <p>
* If a DRBG is not instantiated with a {@link DrbgParameters.Instantiation}
* object explicitly, this implementation instantiates it with a default
* requested strength of 128 bits, no prediction resistance request, and
* no personalization string. These default instantiation parameters can also
* be customized with the {@code securerandom.drbg.config} security property.
* <p>
* This implementation reads fresh entropy from the system default entropy
* source determined by the security property {@code securerandom.source}.
* <p>
* Calling {@link SecureRandom#generateSeed(int)} will directly read
* from this system default entropy source.
* <p>
* This implementation has passed all tests included in the 20151104 version of
* <a href="http://csrc.nist.gov/groups/STM/cavp/documents/drbg/drbgtestvectors.zip">
* The DRBG Test Vectors</a>.
*
* @since 9
*/
public class DrbgParameters {
private DrbgParameters() {
// This class should not be instantiated
}
/**
* The reseedable and prediction resistance capabilities of a DRBG.
* <p>
* When this object is passed to a {@code SecureRandom.getInstance()} call,
* it is the requested minimum capability. When it's returned from
* {@code SecureRandom.getParameters()}, it is the effective capability.
* <p>
* Please note that while the {@code Instantiate_function} defined in
* NIST SP 800-90Ar1 only includes a {@code prediction_resistance_flag}
* parameter, the {@code Capability} type includes an extra value
* {@link #RESEED_ONLY} because reseeding is an optional function.
* If {@code NONE} is used in an {@code Instantiation} object in calling the
* {@code SecureRandom.getInstance} method, the returned DRBG instance
* is not guaranteed to support reseeding. If {@code RESEED_ONLY} or
* {@code PR_AND_RESEED} is used, the instance must support reseeding.
* <p>
* The table below lists possible effective values if a certain
* capability is requested, i.e.
* <blockquote><pre>
* Capability requested = ...;
* SecureRandom s = SecureRandom.getInstance("DRBG",
* DrbgParameters(-1, requested, null));
* Capability effective = ((DrbgParametes.Initiate) s.getParameters())
* .getCapability();</pre>
* </blockquote>
* <table class="striped">
* <caption style="display:none">requested and effective capabilities</caption>
* <thead>
* <tr>
* <th scope="col">Requested Value</th>
* <th scope="col">Possible Effective Values</th>
* </tr>
* </thead>
* <tbody style="text-align:left">
* <tr><th scope="row">NONE</th><td>NONE, RESEED_ONLY, PR_AND_RESEED</td></tr>
* <tr><th scope="row">RESEED_ONLY</th><td>RESEED_ONLY, PR_AND_RESEED</td></tr>
* <tr><th scope="row">PR_AND_RESEED</th><td>PR_AND_RESEED</td></tr>
* </tbody>
* </table>
* <p>
* A DRBG implementation supporting prediction resistance must also
* support reseeding.
*
* @since 9
*/
public enum Capability {
/**
* Both prediction resistance and reseed.
*/
PR_AND_RESEED,
/**
* Reseed but no prediction resistance.
*/
RESEED_ONLY,
/**
* Neither prediction resistance nor reseed.
*/
NONE;
@Override
public String toString() {
return name().toLowerCase(Locale.ROOT);
}
/**
* Returns whether this capability supports reseeding.
*
* @return {@code true} for {@link #PR_AND_RESEED} and
* {@link #RESEED_ONLY}, and {@code false} for {@link #NONE}
*/
public boolean supportsReseeding() {
return this != NONE;
}
/**
* Returns whether this capability supports prediction resistance.
*
* @return {@code true} for {@link #PR_AND_RESEED}, and {@code false}
* for {@link #RESEED_ONLY} and {@link #NONE}
*/
public boolean supportsPredictionResistance() {
return this == PR_AND_RESEED;
}
}
/**
* DRBG parameters for instantiation.
* <p>
* When used in
* {@link SecureRandom#getInstance(String, SecureRandomParameters)}
* or one of the other similar {@code getInstance} calls that take a
* {@code SecureRandomParameters} parameter, it means the
* requested instantiate parameters the newly created {@code SecureRandom}
* object must minimally support. When used as the return value of the
* {@link SecureRandom#getParameters()} method, it means the effective
* instantiate parameters of the {@code SecureRandom} object.
*
* @since 9
*/
public static final class Instantiation
implements SecureRandomParameters {
private final int strength;
private final Capability capability;
private final byte[] personalizationString;
/**
* Returns the security strength in bits.
*
* @return If used in {@code getInstance}, returns the minimum strength
* requested, or -1 if there is no specific request on the strength.
* If used in {@code getParameters}, returns the effective strength.
* The effective strength must be greater than or equal to the minimum
* strength requested.
*/
public int getStrength() {
return strength;
}
/**
* Returns the capability.
*
* @return If used in {@code getInstance}, returns the minimum
* capability requested. If used in {@code getParameters}, returns
* information on the effective prediction resistance flag and
* whether it supports reseeding.
*/
public Capability getCapability() {
return capability;
}
/**
* Returns the personalization string as a byte array.
*
* @return If used in {@code getInstance}, returns the requested
* personalization string as a newly allocated array, or {@code null}
* if no personalization string is requested. The same string should
* be returned in {@code getParameters} as a new copy, or {@code null}
* if no personalization string is requested in {@code getInstance}.
*/
public byte[] getPersonalizationString() {
return (personalizationString == null) ?
null : personalizationString.clone();
}
private Instantiation(int strength, Capability capability,
byte[] personalizationString) {
if (strength < -1) {
throw new IllegalArgumentException(
"Illegal security strength: " + strength);
}
this.strength = strength;
this.capability = capability;
this.personalizationString = (personalizationString == null) ?
null : personalizationString.clone();
}
/**
* Returns a Human-readable string representation of this
* {@code Instantiation}.
*
* @return the string representation
*/
@Override
public String toString() {
// I don't care what personalizationString looks like
return strength + "," + capability + "," + personalizationString;
}
}
/**
* DRBG parameters for random bits generation. It is used in
* {@link SecureRandom#nextBytes(byte[], SecureRandomParameters)}.
*
* @since 9
*/
public static final class NextBytes
implements SecureRandomParameters {
private final int strength;
private final boolean predictionResistance;
private final byte[] additionalInput;
/**
* Returns the security strength requested in bits.
*
* @return the strength requested, or -1 if the effective strength
* should be used.
*/
public int getStrength() {
return strength;
}
/**
* Returns whether prediction resistance is requested.
*
* @return whether prediction resistance is requested
*/
public boolean getPredictionResistance() {
return predictionResistance;
}
/**
* Returns the requested additional input.
*
* @return the requested additional input, {@code null} if not
* requested. A new byte array is returned each time this method
* is called.
*/
public byte[] getAdditionalInput() {
return additionalInput == null? null: additionalInput.clone();
}
private NextBytes(int strength, boolean predictionResistance,
byte[] additionalInput) {
if (strength < -1) {
throw new IllegalArgumentException(
"Illegal security strength: " + strength);
}
this.strength = strength;
this.predictionResistance = predictionResistance;
this.additionalInput = (additionalInput == null) ?
null : additionalInput.clone();
}
}
/**
* DRBG parameters for reseed. It is used in
* {@link SecureRandom#reseed(SecureRandomParameters)}.
*
* @since 9
*/
public static final class Reseed implements SecureRandomParameters {
private final byte[] additionalInput;
private final boolean predictionResistance;
/**
* Returns whether prediction resistance is requested.
*
* @return whether prediction resistance is requested
*/
public boolean getPredictionResistance() {
return predictionResistance;
}
/**
* Returns the requested additional input.
*
* @return the requested additional input, or {@code null} if
* not requested. A new byte array is returned each time this method
* is called.
*/
public byte[] getAdditionalInput() {
return additionalInput == null ? null : additionalInput.clone();
}
private Reseed(boolean predictionResistance, byte[] additionalInput) {
this.predictionResistance = predictionResistance;
this.additionalInput = (additionalInput == null) ?
null : additionalInput.clone();
}
}
/**
* Generates a {@link DrbgParameters.Instantiation} object.
*
* @param strength security strength in bits, -1 for default strength
* if used in {@code getInstance}.
* @param capability capability
* @param personalizationString personalization string as a byte array,
* can be {@code null}. The content of this
* byte array will be copied.
* @return a new {@code Instantiation} object
* @throws NullPointerException if {@code capability} is {@code null}
* @throws IllegalArgumentException if {@code strength} is less than -1
*/
public static Instantiation instantiation(int strength,
Capability capability,
byte[] personalizationString) {
return new Instantiation(strength, Objects.requireNonNull(capability),
personalizationString);
}
/**
* Generates a {@link NextBytes} object.
*
* @param strength requested security strength in bits. If set to -1, the
* effective strength will be used.
* @param predictionResistance prediction resistance requested
* @param additionalInput additional input, can be {@code null}.
* The content of this byte array will be copied.
* @throws IllegalArgumentException if {@code strength} is less than -1
* @return a new {@code NextBytes} object
*/
public static NextBytes nextBytes(int strength,
boolean predictionResistance,
byte[] additionalInput) {
return new NextBytes(strength, predictionResistance, additionalInput);
}
/**
* Generates a {@link Reseed} object.
*
* @param predictionResistance prediction resistance requested
* @param additionalInput additional input, can be {@code null}.
* The content of this byte array will be copied.
* @return a new {@code Reseed} object
*/
public static Reseed reseed(
boolean predictionResistance, byte[] additionalInput) {
return new Reseed(predictionResistance, additionalInput);
}
}

View file

@ -0,0 +1,89 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
/**
* The {@code GeneralSecurityException} class is a generic
* security exception class that provides type safety for all the
* security-related exception classes that extend from it.
*
* @author Jan Luehe
* @since 1.2
*/
public class GeneralSecurityException extends Exception {
private static final long serialVersionUID = 894798122053539237L;
/**
* Constructs a GeneralSecurityException with no detail message.
*/
public GeneralSecurityException() {
super();
}
/**
* Constructs a GeneralSecurityException with the specified detail
* message.
* A detail message is a String that describes this particular
* exception.
*
* @param msg the detail message.
*/
public GeneralSecurityException(String msg) {
super(msg);
}
/**
* Creates a {@code GeneralSecurityException} with the specified
* detail message and cause.
*
* @param message the detail message (which is saved for later retrieval
* by the {@link #getMessage()} method).
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is permitted,
* and indicates that the cause is nonexistent or unknown.)
* @since 1.5
*/
public GeneralSecurityException(String message, Throwable cause) {
super(message, cause);
}
/**
* Creates a {@code GeneralSecurityException} with the specified cause
* and a detail message of {@code (cause==null ? null : cause.toString())}
* (which typically contains the class and detail message of
* {@code cause}).
*
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is permitted,
* and indicates that the cause is nonexistent or unknown.)
* @since 1.5
*/
public GeneralSecurityException(Throwable cause) {
super(cause);
}
}

View file

@ -0,0 +1,57 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
/**
* <p> This interface represents a guard, which is an object that is used
* to protect access to another object.
*
* <p>This interface contains a single method, {@code checkGuard},
* with a single {@code object} argument. {@code checkGuard} is
* invoked (by the GuardedObject {@code getObject} method)
* to determine whether or not to allow access to the object.
*
* @see GuardedObject
*
* @author Roland Schemers
* @author Li Gong
* @since 1.2
*/
public interface Guard {
/**
* Determines whether or not to allow access to the guarded object
* {@code object}. Returns silently if access is allowed.
* Otherwise, throws a SecurityException.
*
* @param object the object being protected by the guard.
*
* @exception SecurityException if access is denied.
*
*/
void checkGuard(Object object) throws SecurityException;
}

View file

@ -0,0 +1,103 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
/**
* A GuardedObject is an object that is used to protect access to
* another object.
*
* <p>A GuardedObject encapsulates a target object and a Guard object,
* such that access to the target object is possible
* only if the Guard object allows it.
* Once an object is encapsulated by a GuardedObject,
* access to that object is controlled by the {@code getObject}
* method, which invokes the
* {@code checkGuard} method on the Guard object that is
* guarding access. If access is not allowed,
* an exception is thrown.
*
* @see Guard
* @see Permission
*
* @author Roland Schemers
* @author Li Gong
* @since 1.2
*/
public class GuardedObject implements java.io.Serializable {
private static final long serialVersionUID = -5240450096227834308L;
private Object object; // the object we are guarding
private Guard guard; // the guard
/**
* Constructs a GuardedObject using the specified object and guard.
* If the Guard object is null, then no restrictions will
* be placed on who can access the object.
*
* @param object the object to be guarded.
*
* @param guard the Guard object that guards access to the object.
*/
public GuardedObject(Object object, Guard guard)
{
this.guard = guard;
this.object = object;
}
/**
* Retrieves the guarded object, or throws an exception if access
* to the guarded object is denied by the guard.
*
* @return the guarded object.
*
* @exception SecurityException if access to the guarded object is
* denied.
*/
public Object getObject()
throws SecurityException
{
if (guard != null)
guard.checkGuard(object);
return object;
}
/**
* Writes this object out to a stream (i.e., serializes it).
* We check the guard if there is one.
*/
private void writeObject(java.io.ObjectOutputStream oos)
throws java.io.IOException
{
if (guard != null)
guard.checkGuard(object);
oos.defaultWriteObject();
}
}

View file

@ -0,0 +1,496 @@
/*
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
import java.io.Serializable;
import java.util.*;
/**
* <p>This class represents identities: real-world objects such as people,
* companies or organizations whose identities can be authenticated using
* their public keys. Identities may also be more abstract (or concrete)
* constructs, such as daemon threads or smart cards.
*
* <p>All Identity objects have a name and a public key. Names are
* immutable. Identities may also be scoped. That is, if an Identity is
* specified to have a particular scope, then the name and public
* key of the Identity are unique within that scope.
*
* <p>An Identity also has a set of certificates (all certifying its own
* public key). The Principal names specified in these certificates need
* not be the same, only the key.
*
* <p>An Identity can be subclassed, to include postal and email addresses,
* telephone numbers, images of faces and logos, and so on.
*
* @see IdentityScope
* @see Signer
* @see Principal
*
* @author Benjamin Renaud
* @since 1.1
* @deprecated This class is no longer used. Its functionality has been
* replaced by {@code java.security.KeyStore}, the
* {@code java.security.cert} package, and
* {@code java.security.Principal}.
*/
@Deprecated(since="1.2")
public abstract class Identity implements Principal, Serializable {
/** use serialVersionUID from JDK 1.1.x for interoperability */
private static final long serialVersionUID = 3609922007826600659L;
/**
* The name for this identity.
*
* @serial
*/
private String name;
/**
* The public key for this identity.
*
* @serial
*/
private PublicKey publicKey;
/**
* Generic, descriptive information about the identity.
*
* @serial
*/
String info = "No further information available.";
/**
* The scope of the identity.
*
* @serial
*/
IdentityScope scope;
/**
* The certificates for this identity.
*
* @serial
*/
Vector<Certificate> certificates;
/**
* Constructor for serialization only.
*/
protected Identity() {
this("restoring...");
}
/**
* Constructs an identity with the specified name and scope.
*
* @param name the identity name.
* @param scope the scope of the identity.
*
* @exception KeyManagementException if there is already an identity
* with the same name in the scope.
*/
public Identity(String name, IdentityScope scope) throws
KeyManagementException {
this(name);
if (scope != null) {
scope.addIdentity(this);
}
this.scope = scope;
}
/**
* Constructs an identity with the specified name and no scope.
*
* @param name the identity name.
*/
public Identity(String name) {
this.name = name;
}
/**
* Returns this identity's name.
*
* @return the name of this identity.
*/
public final String getName() {
return name;
}
/**
* Returns this identity's scope.
*
* @return the scope of this identity.
*/
public final IdentityScope getScope() {
return scope;
}
/**
* Returns this identity's public key.
*
* @return the public key for this identity.
*
* @see #setPublicKey
*/
public PublicKey getPublicKey() {
return publicKey;
}
/**
* Sets this identity's public key. The old key and all of this
* identity's certificates are removed by this operation.
*
* <p>First, if there is a security manager, its {@code checkSecurityAccess}
* method is called with {@code "setIdentityPublicKey"}
* as its argument to see if it's ok to set the public key.
*
* @param key the public key for this identity.
*
* @exception KeyManagementException if another identity in the
* identity's scope has the same public key, or if another exception occurs.
*
* @exception SecurityException if a security manager exists and its
* {@code checkSecurityAccess} method doesn't allow
* setting the public key.
*
* @see #getPublicKey
* @see SecurityManager#checkSecurityAccess
*/
/* Should we throw an exception if this is already set? */
public void setPublicKey(PublicKey key) throws KeyManagementException {
check("setIdentityPublicKey");
this.publicKey = key;
certificates = new Vector<>();
}
/**
* Specifies a general information string for this identity.
*
* <p>First, if there is a security manager, its {@code checkSecurityAccess}
* method is called with {@code "setIdentityInfo"}
* as its argument to see if it's ok to specify the information string.
*
* @param info the information string.
*
* @exception SecurityException if a security manager exists and its
* {@code checkSecurityAccess} method doesn't allow
* setting the information string.
*
* @see #getInfo
* @see SecurityManager#checkSecurityAccess
*/
public void setInfo(String info) {
check("setIdentityInfo");
this.info = info;
}
/**
* Returns general information previously specified for this identity.
*
* @return general information about this identity.
*
* @see #setInfo
*/
public String getInfo() {
return info;
}
/**
* Adds a certificate for this identity. If the identity has a public
* key, the public key in the certificate must be the same, and if
* the identity does not have a public key, the identity's
* public key is set to be that specified in the certificate.
*
* <p>First, if there is a security manager, its {@code checkSecurityAccess}
* method is called with {@code "addIdentityCertificate"}
* as its argument to see if it's ok to add a certificate.
*
* @param certificate the certificate to be added.
*
* @exception KeyManagementException if the certificate is not valid,
* if the public key in the certificate being added conflicts with
* this identity's public key, or if another exception occurs.
*
* @exception SecurityException if a security manager exists and its
* {@code checkSecurityAccess} method doesn't allow
* adding a certificate.
*
* @see SecurityManager#checkSecurityAccess
*/
public void addCertificate(Certificate certificate)
throws KeyManagementException {
check("addIdentityCertificate");
if (certificates == null) {
certificates = new Vector<>();
}
if (publicKey != null) {
if (!keyEquals(publicKey, certificate.getPublicKey())) {
throw new KeyManagementException(
"public key different from cert public key");
}
} else {
publicKey = certificate.getPublicKey();
}
certificates.addElement(certificate);
}
private boolean keyEquals(PublicKey aKey, PublicKey anotherKey) {
String aKeyFormat = aKey.getFormat();
String anotherKeyFormat = anotherKey.getFormat();
if ((aKeyFormat == null) ^ (anotherKeyFormat == null))
return false;
if (aKeyFormat != null && anotherKeyFormat != null)
if (!aKeyFormat.equalsIgnoreCase(anotherKeyFormat))
return false;
return java.util.Arrays.equals(aKey.getEncoded(),
anotherKey.getEncoded());
}
/**
* Removes a certificate from this identity.
*
* <p>First, if there is a security manager, its {@code checkSecurityAccess}
* method is called with {@code "removeIdentityCertificate"}
* as its argument to see if it's ok to remove a certificate.
*
* @param certificate the certificate to be removed.
*
* @exception KeyManagementException if the certificate is
* missing, or if another exception occurs.
*
* @exception SecurityException if a security manager exists and its
* {@code checkSecurityAccess} method doesn't allow
* removing a certificate.
*
* @see SecurityManager#checkSecurityAccess
*/
public void removeCertificate(Certificate certificate)
throws KeyManagementException {
check("removeIdentityCertificate");
if (certificates != null) {
certificates.removeElement(certificate);
}
}
/**
* Returns a copy of all the certificates for this identity.
*
* @return a copy of all the certificates for this identity.
*/
public Certificate[] certificates() {
if (certificates == null) {
return new Certificate[0];
}
int len = certificates.size();
Certificate[] certs = new Certificate[len];
certificates.copyInto(certs);
return certs;
}
/**
* Tests for equality between the specified object and this identity.
* This first tests to see if the entities actually refer to the same
* object, in which case it returns true. Next, it checks to see if
* the entities have the same name and the same scope. If they do,
* the method returns true. Otherwise, it calls
* {@link #identityEquals(Identity) identityEquals}, which subclasses should
* override.
*
* @param identity the object to test for equality with this identity.
*
* @return true if the objects are considered equal, false otherwise.
*
* @see #identityEquals
*/
public final boolean equals(Object identity) {
if (identity == this) {
return true;
}
if (identity instanceof Identity) {
Identity i = (Identity)identity;
if (this.fullName().equals(i.fullName())) {
return true;
} else {
return identityEquals(i);
}
}
return false;
}
/**
* Tests for equality between the specified identity and this identity.
* This method should be overriden by subclasses to test for equality.
* The default behavior is to return true if the names and public keys
* are equal.
*
* @param identity the identity to test for equality with this identity.
*
* @return true if the identities are considered equal, false
* otherwise.
*
* @see #equals
*/
protected boolean identityEquals(Identity identity) {
if (!name.equalsIgnoreCase(identity.name))
return false;
if ((publicKey == null) ^ (identity.publicKey == null))
return false;
if (publicKey != null && identity.publicKey != null)
if (!publicKey.equals(identity.publicKey))
return false;
return true;
}
/**
* Returns a parsable name for identity: identityName.scopeName
*/
String fullName() {
String parsable = name;
if (scope != null) {
parsable += "." + scope.getName();
}
return parsable;
}
/**
* Returns a short string describing this identity, telling its
* name and its scope (if any).
*
* <p>First, if there is a security manager, its {@code checkSecurityAccess}
* method is called with {@code "printIdentity"}
* as its argument to see if it's ok to return the string.
*
* @return information about this identity, such as its name and the
* name of its scope (if any).
*
* @exception SecurityException if a security manager exists and its
* {@code checkSecurityAccess} method doesn't allow
* returning a string describing this identity.
*
* @see SecurityManager#checkSecurityAccess
*/
public String toString() {
check("printIdentity");
String printable = name;
if (scope != null) {
printable += "[" + scope.getName() + "]";
}
return printable;
}
/**
* Returns a string representation of this identity, with
* optionally more details than that provided by the
* {@code toString} method without any arguments.
*
* <p>First, if there is a security manager, its {@code checkSecurityAccess}
* method is called with {@code "printIdentity"}
* as its argument to see if it's ok to return the string.
*
* @param detailed whether or not to provide detailed information.
*
* @return information about this identity. If {@code detailed}
* is true, then this method returns more information than that
* provided by the {@code toString} method without any arguments.
*
* @exception SecurityException if a security manager exists and its
* {@code checkSecurityAccess} method doesn't allow
* returning a string describing this identity.
*
* @see #toString
* @see SecurityManager#checkSecurityAccess
*/
public String toString(boolean detailed) {
String out = toString();
if (detailed) {
out += "\n";
out += printKeys();
out += "\n" + printCertificates();
if (info != null) {
out += "\n\t" + info;
} else {
out += "\n\tno additional information available.";
}
}
return out;
}
String printKeys() {
String key = "";
if (publicKey != null) {
key = "\tpublic key initialized";
} else {
key = "\tno public key";
}
return key;
}
String printCertificates() {
String out = "";
if (certificates == null) {
return "\tno certificates";
} else {
out += "\tcertificates: \n";
int i = 1;
for (Certificate cert : certificates) {
out += "\tcertificate " + i++ +
"\tfor : " + cert.getPrincipal() + "\n";
out += "\t\t\tfrom : " +
cert.getGuarantor() + "\n";
}
}
return out;
}
/**
* Returns a hashcode for this identity.
*
* @return a hashcode for this identity.
*/
public int hashCode() {
return name.hashCode();
}
private static void check(String directive) {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkSecurityAccess(directive);
}
}
}

View file

@ -0,0 +1,258 @@
/*
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
import java.io.Serializable;
import java.util.Enumeration;
import java.util.Properties;
/**
* <p>This class represents a scope for identities. It is an Identity
* itself, and therefore has a name and can have a scope. It can also
* optionally have a public key and associated certificates.
*
* <p>An IdentityScope can contain Identity objects of all kinds, including
* Signers. All types of Identity objects can be retrieved, added, and
* removed using the same methods. Note that it is possible, and in fact
* expected, that different types of identity scopes will
* apply different policies for their various operations on the
* various types of Identities.
*
* <p>There is a one-to-one mapping between keys and identities, and
* there can only be one copy of one key per scope. For example, suppose
* <b>Acme Software, Inc</b> is a software publisher known to a user.
* Suppose it is an Identity, that is, it has a public key, and a set of
* associated certificates. It is named in the scope using the name
* "Acme Software". No other named Identity in the scope has the same
* public key. Of course, none has the same name as well.
*
* @see Identity
* @see Signer
* @see Principal
* @see Key
*
* @author Benjamin Renaud
* @since 1.1
*
* @deprecated This class is no longer used. Its functionality has been
* replaced by {@code java.security.KeyStore}, the
* {@code java.security.cert} package, and
* {@code java.security.Principal}.
*/
@Deprecated(since="1.2")
public abstract
class IdentityScope extends Identity {
private static final long serialVersionUID = -2337346281189773310L;
/* The system's scope */
private static IdentityScope scope;
// initialize the system scope
private static void initializeSystemScope() {
String classname = AccessController.doPrivileged(
new PrivilegedAction<>() {
public String run() {
return Security.getProperty("system.scope");
}
});
if (classname == null) {
return;
} else {
try {
Class.forName(classname);
} catch (ClassNotFoundException e) {
//Security.error("unable to establish a system scope from " +
// classname);
e.printStackTrace();
}
}
}
/**
* This constructor is used for serialization only and should not
* be used by subclasses.
*/
protected IdentityScope() {
this("restoring...");
}
/**
* Constructs a new identity scope with the specified name.
*
* @param name the scope name.
*/
public IdentityScope(String name) {
super(name);
}
/**
* Constructs a new identity scope with the specified name and scope.
*
* @param name the scope name.
* @param scope the scope for the new identity scope.
*
* @exception KeyManagementException if there is already an identity
* with the same name in the scope.
*/
public IdentityScope(String name, IdentityScope scope)
throws KeyManagementException {
super(name, scope);
}
/**
* Returns the system's identity scope.
*
* @return the system's identity scope, or {@code null} if none has been
* set.
*
* @see #setSystemScope
*/
public static IdentityScope getSystemScope() {
if (scope == null) {
initializeSystemScope();
}
return scope;
}
/**
* Sets the system's identity scope.
*
* <p>First, if there is a security manager, its
* {@code checkSecurityAccess}
* method is called with {@code "setSystemScope"}
* as its argument to see if it's ok to set the identity scope.
*
* @param scope the scope to set.
*
* @exception SecurityException if a security manager exists and its
* {@code checkSecurityAccess} method doesn't allow
* setting the identity scope.
*
* @see #getSystemScope
* @see SecurityManager#checkSecurityAccess
*/
protected static void setSystemScope(IdentityScope scope) {
check("setSystemScope");
IdentityScope.scope = scope;
}
/**
* Returns the number of identities within this identity scope.
*
* @return the number of identities within this identity scope.
*/
public abstract int size();
/**
* Returns the identity in this scope with the specified name (if any).
*
* @param name the name of the identity to be retrieved.
*
* @return the identity named {@code name}, or null if there are
* no identities named {@code name} in this scope.
*/
public abstract Identity getIdentity(String name);
/**
* Retrieves the identity whose name is the same as that of the
* specified principal. (Note: Identity implements Principal.)
*
* @param principal the principal corresponding to the identity
* to be retrieved.
*
* @return the identity whose name is the same as that of the
* principal, or null if there are no identities of the same name
* in this scope.
*/
public Identity getIdentity(Principal principal) {
return getIdentity(principal.getName());
}
/**
* Retrieves the identity with the specified public key.
*
* @param key the public key for the identity to be returned.
*
* @return the identity with the given key, or null if there are
* no identities in this scope with that key.
*/
public abstract Identity getIdentity(PublicKey key);
/**
* Adds an identity to this identity scope.
*
* @param identity the identity to be added.
*
* @exception KeyManagementException if the identity is not
* valid, a name conflict occurs, another identity has the same
* public key as the identity being added, or another exception
* occurs. */
public abstract void addIdentity(Identity identity)
throws KeyManagementException;
/**
* Removes an identity from this identity scope.
*
* @param identity the identity to be removed.
*
* @exception KeyManagementException if the identity is missing,
* or another exception occurs.
*/
public abstract void removeIdentity(Identity identity)
throws KeyManagementException;
/**
* Returns an enumeration of all identities in this identity scope.
*
* @return an enumeration of all identities in this identity scope.
*/
public abstract Enumeration<Identity> identities();
/**
* Returns a string representation of this identity scope, including
* its name, its scope name, and the number of identities in this
* identity scope.
*
* @return a string representation of this identity scope.
*/
public String toString() {
return super.toString() + "[" + size() + "]";
}
private static void check(String directive) {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkSecurityAccess(directive);
}
}
}

View file

@ -0,0 +1,97 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
/**
* This is the exception for invalid or inappropriate algorithm parameters.
*
* @author Jan Luehe
*
*
* @see AlgorithmParameters
* @see java.security.spec.AlgorithmParameterSpec
*
* @since 1.2
*/
public class InvalidAlgorithmParameterException
extends GeneralSecurityException {
private static final long serialVersionUID = 2864672297499471472L;
/**
* Constructs an InvalidAlgorithmParameterException with no detail
* message.
* A detail message is a String that describes this particular
* exception.
*/
public InvalidAlgorithmParameterException() {
super();
}
/**
* Constructs an InvalidAlgorithmParameterException with the specified
* detail message.
* A detail message is a String that describes this
* particular exception.
*
* @param msg the detail message.
*/
public InvalidAlgorithmParameterException(String msg) {
super(msg);
}
/**
* Creates an {@code InvalidAlgorithmParameterException} with the
* specified detail message and cause.
*
* @param message the detail message (which is saved for later retrieval
* by the {@link #getMessage()} method).
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is permitted,
* and indicates that the cause is nonexistent or unknown.)
* @since 1.5
*/
public InvalidAlgorithmParameterException(String message, Throwable cause) {
super(message, cause);
}
/**
* Creates an {@code InvalidAlgorithmParameterException} with the
* specified cause and a detail message of
* {@code (cause==null ? null : cause.toString())}
* (which typically contains the class and detail message of
* {@code cause}).
*
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is permitted,
* and indicates that the cause is nonexistent or unknown.)
* @since 1.5
*/
public InvalidAlgorithmParameterException(Throwable cause) {
super(cause);
}
}

View file

@ -0,0 +1,90 @@
/*
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
/**
* This is the exception for invalid Keys (invalid encoding, wrong
* length, uninitialized, etc).
*
* @author Benjamin Renaud
* @since 1.1
*/
public class InvalidKeyException extends KeyException {
private static final long serialVersionUID = 5698479920593359816L;
/**
* Constructs an InvalidKeyException with no detail message. A
* detail message is a String that describes this particular
* exception.
*/
public InvalidKeyException() {
super();
}
/**
* Constructs an InvalidKeyException with the specified detail
* message. A detail message is a String that describes this
* particular exception.
*
* @param msg the detail message.
*/
public InvalidKeyException(String msg) {
super(msg);
}
/**
* Creates an {@code InvalidKeyException} with the specified
* detail message and cause.
*
* @param message the detail message (which is saved for later retrieval
* by the {@link #getMessage()} method).
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is permitted,
* and indicates that the cause is nonexistent or unknown.)
* @since 1.5
*/
public InvalidKeyException(String message, Throwable cause) {
super(message, cause);
}
/**
* Creates an {@code InvalidKeyException} with the specified cause
* and a detail message of {@code (cause==null ? null : cause.toString())}
* (which typically contains the class and detail message of
* {@code cause}).
*
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is permitted,
* and indicates that the cause is nonexistent or unknown.)
* @since 1.5
*/
public InvalidKeyException(Throwable cause) {
super(cause);
}
}

View file

@ -0,0 +1,60 @@
/*
* Copyright (c) 1996, 2003, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
/**
* This exception, designed for use by the JCA/JCE engine classes,
* is thrown when an invalid parameter is passed
* to a method.
*
* @author Benjamin Renaud
* @since 1.1
*/
public class InvalidParameterException extends IllegalArgumentException {
private static final long serialVersionUID = -857968536935667808L;
/**
* Constructs an InvalidParameterException with no detail message.
* A detail message is a String that describes this particular
* exception.
*/
public InvalidParameterException() {
super();
}
/**
* Constructs an InvalidParameterException with the specified
* detail message. A detail message is a String that describes
* this particular exception.
*
* @param msg the detail message.
*/
public InvalidParameterException(String msg) {
super(msg);
}
}

View file

@ -0,0 +1,153 @@
/*
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
/**
* The Key interface is the top-level interface for all keys. It
* defines the functionality shared by all key objects. All keys
* have three characteristics:
*
* <UL>
*
* <LI>An Algorithm
*
* <P>This is the key algorithm for that key. The key algorithm is usually
* an encryption or asymmetric operation algorithm (such as DSA or
* RSA), which will work with those algorithms and with related
* algorithms (such as MD5 with RSA, SHA-1 with RSA, Raw DSA, etc.)
* The name of the algorithm of a key is obtained using the
* {@link #getAlgorithm() getAlgorithm} method.
*
* <LI>An Encoded Form
*
* <P>This is an external encoded form for the key used when a standard
* representation of the key is needed outside the Java Virtual Machine,
* as when transmitting the key to some other party. The key
* is encoded according to a standard format (such as
* X.509 {@code SubjectPublicKeyInfo} or PKCS#8), and
* is returned using the {@link #getEncoded() getEncoded} method.
* Note: The syntax of the ASN.1 type {@code SubjectPublicKeyInfo}
* is defined as follows:
*
* <pre>
* SubjectPublicKeyInfo ::= SEQUENCE {
* algorithm AlgorithmIdentifier,
* subjectPublicKey BIT STRING }
*
* AlgorithmIdentifier ::= SEQUENCE {
* algorithm OBJECT IDENTIFIER,
* parameters ANY DEFINED BY algorithm OPTIONAL }
* </pre>
*
* For more information, see
* <a href="http://tools.ietf.org/html/rfc5280">RFC 5280:
* Internet X.509 Public Key Infrastructure Certificate and CRL Profile</a>.
*
* <LI>A Format
*
* <P>This is the name of the format of the encoded key. It is returned
* by the {@link #getFormat() getFormat} method.
*
* </UL>
*
* Keys are generally obtained through key generators, certificates,
* or various Identity classes used to manage keys.
* Keys may also be obtained from key specifications (transparent
* representations of the underlying key material) through the use of a key
* factory (see {@link KeyFactory}).
*
* <p> A Key should use KeyRep as its serialized representation.
* Note that a serialized Key may contain sensitive information
* which should not be exposed in untrusted environments. See the
* <a href="{@docRoot}/../specs/serialization/security.html">
* Security Appendix</a>
* of the Serialization Specification for more information.
*
* @see PublicKey
* @see PrivateKey
* @see KeyPair
* @see KeyPairGenerator
* @see KeyFactory
* @see KeyRep
* @see java.security.spec.KeySpec
* @see Identity
* @see Signer
*
* @author Benjamin Renaud
* @since 1.1
*/
public interface Key extends java.io.Serializable {
// Declare serialVersionUID to be compatible with JDK1.1
/**
* The class fingerprint that is set to indicate
* serialization compatibility with a previous
* version of the class.
*/
static final long serialVersionUID = 6603384152749567654L;
/**
* Returns the standard algorithm name for this key. For
* example, "DSA" would indicate that this key is a DSA key.
* See the <a href=
* "{@docRoot}/../specs/security/standard-names.html">
* Java Security Standard Algorithm Names</a> document
* for more information.
*
* @return the name of the algorithm associated with this key.
*/
public String getAlgorithm();
/**
* Returns the name of the primary encoding format of this key,
* or null if this key does not support encoding.
* The primary encoding format is
* named in terms of the appropriate ASN.1 data format, if an
* ASN.1 specification for this key exists.
* For example, the name of the ASN.1 data format for public
* keys is <I>SubjectPublicKeyInfo</I>, as
* defined by the X.509 standard; in this case, the returned format is
* {@code "X.509"}. Similarly,
* the name of the ASN.1 data format for private keys is
* <I>PrivateKeyInfo</I>,
* as defined by the PKCS #8 standard; in this case, the returned format is
* {@code "PKCS#8"}.
*
* @return the primary encoding format of the key.
*/
public String getFormat();
/**
* Returns the key in its primary encoding format, or null
* if this key does not support encoding.
*
* @return the encoded key, or null if the key does not support
* encoding.
*/
public byte[] getEncoded();
}

View file

@ -0,0 +1,91 @@
/*
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
/**
* This is the basic key exception.
*
* @see Key
* @see InvalidKeyException
* @see KeyManagementException
*
* @author Benjamin Renaud
* @since 1.1
*/
public class KeyException extends GeneralSecurityException {
private static final long serialVersionUID = -7483676942812432108L;
/**
* Constructs a KeyException with no detail message. A detail
* message is a String that describes this particular exception.
*/
public KeyException() {
super();
}
/**
* Constructs a KeyException with the specified detail message.
* A detail message is a String that describes this particular
* exception.
*
* @param msg the detail message.
*/
public KeyException(String msg) {
super(msg);
}
/**
* Creates a {@code KeyException} with the specified
* detail message and cause.
*
* @param message the detail message (which is saved for later retrieval
* by the {@link #getMessage()} method).
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is permitted,
* and indicates that the cause is nonexistent or unknown.)
* @since 1.5
*/
public KeyException(String message, Throwable cause) {
super(message, cause);
}
/**
* Creates a {@code KeyException} with the specified cause
* and a detail message of {@code (cause==null ? null : cause.toString())}
* (which typically contains the class and detail message of
* {@code cause}).
*
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is permitted,
* and indicates that the cause is nonexistent or unknown.)
* @since 1.5
*/
public KeyException(Throwable cause) {
super(cause);
}
}

View file

@ -0,0 +1,494 @@
/*
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
import java.util.*;
import java.security.Provider.Service;
import java.security.spec.KeySpec;
import java.security.spec.InvalidKeySpecException;
import sun.security.util.Debug;
import sun.security.jca.*;
import sun.security.jca.GetInstance.Instance;
/**
* Key factories are used to convert <I>keys</I> (opaque
* cryptographic keys of type {@code Key}) into <I>key specifications</I>
* (transparent representations of the underlying key material), and vice
* versa.
*
* <P> Key factories are bi-directional. That is, they allow you to build an
* opaque key object from a given key specification (key material), or to
* retrieve the underlying key material of a key object in a suitable format.
*
* <P> Multiple compatible key specifications may exist for the same key.
* For example, a DSA public key may be specified using
* {@code DSAPublicKeySpec} or
* {@code X509EncodedKeySpec}. A key factory can be used to translate
* between compatible key specifications.
*
* <P> The following is an example of how to use a key factory in order to
* instantiate a DSA public key from its encoding.
* Assume Alice has received a digital signature from Bob.
* Bob also sent her his public key (in encoded format) to verify
* his signature. Alice then performs the following actions:
*
* <pre>
* X509EncodedKeySpec bobPubKeySpec = new X509EncodedKeySpec(bobEncodedPubKey);
* KeyFactory keyFactory = KeyFactory.getInstance("DSA");
* PublicKey bobPubKey = keyFactory.generatePublic(bobPubKeySpec);
* Signature sig = Signature.getInstance("DSA");
* sig.initVerify(bobPubKey);
* sig.update(data);
* sig.verify(signature);
* </pre>
*
* <p> Every implementation of the Java platform is required to support the
* following standard {@code KeyFactory} algorithms:
* <ul>
* <li>{@code DiffieHellman}</li>
* <li>{@code DSA}</li>
* <li>{@code RSA}</li>
* </ul>
* These algorithms are described in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#keyfactory-algorithms">
* KeyFactory section</a> of the
* Java Security Standard Algorithm Names Specification.
* Consult the release documentation for your implementation to see if any
* other algorithms are supported.
*
* @author Jan Luehe
*
* @see Key
* @see PublicKey
* @see PrivateKey
* @see java.security.spec.KeySpec
* @see java.security.spec.DSAPublicKeySpec
* @see java.security.spec.X509EncodedKeySpec
*
* @since 1.2
*/
public class KeyFactory {
private static final Debug debug =
Debug.getInstance("jca", "KeyFactory");
// The algorithm associated with this key factory
private final String algorithm;
// The provider
private Provider provider;
// The provider implementation (delegate)
private volatile KeyFactorySpi spi;
// lock for mutex during provider selection
private final Object lock = new Object();
// remaining services to try in provider selection
// null once provider is selected
private Iterator<Service> serviceIterator;
/**
* Creates a KeyFactory object.
*
* @param keyFacSpi the delegate
* @param provider the provider
* @param algorithm the name of the algorithm
* to associate with this {@code KeyFactory}
*/
protected KeyFactory(KeyFactorySpi keyFacSpi, Provider provider,
String algorithm) {
this.spi = keyFacSpi;
this.provider = provider;
this.algorithm = algorithm;
}
private KeyFactory(String algorithm) throws NoSuchAlgorithmException {
this.algorithm = algorithm;
List<Service> list = GetInstance.getServices("KeyFactory", algorithm);
serviceIterator = list.iterator();
// fetch and instantiate initial spi
if (nextSpi(null) == null) {
throw new NoSuchAlgorithmException
(algorithm + " KeyFactory not available");
}
}
/**
* Returns a KeyFactory object that converts
* public/private keys of the specified algorithm.
*
* <p> This method traverses the list of registered security Providers,
* starting with the most preferred Provider.
* A new KeyFactory object encapsulating the
* KeyFactorySpi implementation from the first
* Provider that supports the specified algorithm is returned.
*
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @implNote
* The JDK Reference Implementation additionally uses the
* {@code jdk.security.provider.preferred}
* {@link Security#getProperty(String) Security} property to determine
* the preferred provider order for the specified algorithm. This
* may be different than the order of providers returned by
* {@link Security#getProviders() Security.getProviders()}.
*
* @param algorithm the name of the requested key algorithm.
* See the KeyFactory section in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#keyfactory-algorithms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard algorithm names.
*
* @return the new {@code KeyFactory} object
*
* @throws NoSuchAlgorithmException if no {@code Provider} supports a
* {@code KeyFactorySpi} implementation for the
* specified algorithm
*
* @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see Provider
*/
public static KeyFactory getInstance(String algorithm)
throws NoSuchAlgorithmException {
Objects.requireNonNull(algorithm, "null algorithm name");
return new KeyFactory(algorithm);
}
/**
* Returns a KeyFactory object that converts
* public/private keys of the specified algorithm.
*
* <p> A new KeyFactory object encapsulating the
* KeyFactorySpi implementation from the specified provider
* is returned. The specified provider must be registered
* in the security provider list.
*
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param algorithm the name of the requested key algorithm.
* See the KeyFactory section in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#keyfactory-algorithms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard algorithm names.
*
* @param provider the name of the provider.
*
* @return the new {@code KeyFactory} object
*
* @throws IllegalArgumentException if the provider name is {@code null}
* or empty
*
* @throws NoSuchAlgorithmException if a {@code KeyFactorySpi}
* implementation for the specified algorithm is not
* available from the specified provider
*
* @throws NoSuchProviderException if the specified provider is not
* registered in the security provider list
*
* @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see Provider
*/
public static KeyFactory getInstance(String algorithm, String provider)
throws NoSuchAlgorithmException, NoSuchProviderException {
Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = GetInstance.getInstance("KeyFactory",
KeyFactorySpi.class, algorithm, provider);
return new KeyFactory((KeyFactorySpi)instance.impl,
instance.provider, algorithm);
}
/**
* Returns a KeyFactory object that converts
* public/private keys of the specified algorithm.
*
* <p> A new KeyFactory object encapsulating the
* KeyFactorySpi implementation from the specified Provider
* object is returned. Note that the specified Provider object
* does not have to be registered in the provider list.
*
* @param algorithm the name of the requested key algorithm.
* See the KeyFactory section in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#keyfactory-algorithms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard algorithm names.
*
* @param provider the provider.
*
* @return the new {@code KeyFactory} object
*
* @throws IllegalArgumentException if the specified provider is
* {@code null}
*
* @throws NoSuchAlgorithmException if a {@code KeyFactorySpi}
* implementation for the specified algorithm is not available
* from the specified {@code Provider} object
*
* @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see Provider
*
* @since 1.4
*/
public static KeyFactory getInstance(String algorithm, Provider provider)
throws NoSuchAlgorithmException {
Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = GetInstance.getInstance("KeyFactory",
KeyFactorySpi.class, algorithm, provider);
return new KeyFactory((KeyFactorySpi)instance.impl,
instance.provider, algorithm);
}
/**
* Returns the provider of this key factory object.
*
* @return the provider of this key factory object
*/
public final Provider getProvider() {
synchronized (lock) {
// disable further failover after this call
serviceIterator = null;
return provider;
}
}
/**
* Gets the name of the algorithm
* associated with this {@code KeyFactory}.
*
* @return the name of the algorithm associated with this
* {@code KeyFactory}
*/
public final String getAlgorithm() {
return this.algorithm;
}
/**
* Update the active KeyFactorySpi of this class and return the next
* implementation for failover. If no more implemenations are
* available, this method returns null. However, the active spi of
* this class is never set to null.
*/
private KeyFactorySpi nextSpi(KeyFactorySpi oldSpi) {
synchronized (lock) {
// somebody else did a failover concurrently
// try that spi now
if ((oldSpi != null) && (oldSpi != spi)) {
return spi;
}
if (serviceIterator == null) {
return null;
}
while (serviceIterator.hasNext()) {
Service s = serviceIterator.next();
try {
Object obj = s.newInstance(null);
if (obj instanceof KeyFactorySpi == false) {
continue;
}
KeyFactorySpi spi = (KeyFactorySpi)obj;
provider = s.getProvider();
this.spi = spi;
return spi;
} catch (NoSuchAlgorithmException e) {
// ignore
}
}
serviceIterator = null;
return null;
}
}
/**
* Generates a public key object from the provided key specification
* (key material).
*
* @param keySpec the specification (key material) of the public key.
*
* @return the public key.
*
* @exception InvalidKeySpecException if the given key specification
* is inappropriate for this key factory to produce a public key.
*/
public final PublicKey generatePublic(KeySpec keySpec)
throws InvalidKeySpecException {
if (serviceIterator == null) {
return spi.engineGeneratePublic(keySpec);
}
Exception failure = null;
KeyFactorySpi mySpi = spi;
do {
try {
return mySpi.engineGeneratePublic(keySpec);
} catch (Exception e) {
if (failure == null) {
failure = e;
}
mySpi = nextSpi(mySpi);
}
} while (mySpi != null);
if (failure instanceof RuntimeException) {
throw (RuntimeException)failure;
}
if (failure instanceof InvalidKeySpecException) {
throw (InvalidKeySpecException)failure;
}
throw new InvalidKeySpecException
("Could not generate public key", failure);
}
/**
* Generates a private key object from the provided key specification
* (key material).
*
* @param keySpec the specification (key material) of the private key.
*
* @return the private key.
*
* @exception InvalidKeySpecException if the given key specification
* is inappropriate for this key factory to produce a private key.
*/
public final PrivateKey generatePrivate(KeySpec keySpec)
throws InvalidKeySpecException {
if (serviceIterator == null) {
return spi.engineGeneratePrivate(keySpec);
}
Exception failure = null;
KeyFactorySpi mySpi = spi;
do {
try {
return mySpi.engineGeneratePrivate(keySpec);
} catch (Exception e) {
if (failure == null) {
failure = e;
}
mySpi = nextSpi(mySpi);
}
} while (mySpi != null);
if (failure instanceof RuntimeException) {
throw (RuntimeException)failure;
}
if (failure instanceof InvalidKeySpecException) {
throw (InvalidKeySpecException)failure;
}
throw new InvalidKeySpecException
("Could not generate private key", failure);
}
/**
* Returns a specification (key material) of the given key object.
* {@code keySpec} identifies the specification class in which
* the key material should be returned. It could, for example, be
* {@code DSAPublicKeySpec.class}, to indicate that the
* key material should be returned in an instance of the
* {@code DSAPublicKeySpec} class.
*
* @param <T> the type of the key specification to be returned
*
* @param key the key.
*
* @param keySpec the specification class in which
* the key material should be returned.
*
* @return the underlying key specification (key material) in an instance
* of the requested specification class.
*
* @exception InvalidKeySpecException if the requested key specification is
* inappropriate for the given key, or the given key cannot be processed
* (e.g., the given key has an unrecognized algorithm or format).
*/
public final <T extends KeySpec> T getKeySpec(Key key, Class<T> keySpec)
throws InvalidKeySpecException {
if (serviceIterator == null) {
return spi.engineGetKeySpec(key, keySpec);
}
Exception failure = null;
KeyFactorySpi mySpi = spi;
do {
try {
return mySpi.engineGetKeySpec(key, keySpec);
} catch (Exception e) {
if (failure == null) {
failure = e;
}
mySpi = nextSpi(mySpi);
}
} while (mySpi != null);
if (failure instanceof RuntimeException) {
throw (RuntimeException)failure;
}
if (failure instanceof InvalidKeySpecException) {
throw (InvalidKeySpecException)failure;
}
throw new InvalidKeySpecException
("Could not get key spec", failure);
}
/**
* Translates a key object, whose provider may be unknown or potentially
* untrusted, into a corresponding key object of this key factory.
*
* @param key the key whose provider is unknown or untrusted.
*
* @return the translated key.
*
* @exception InvalidKeyException if the given key cannot be processed
* by this key factory.
*/
public final Key translateKey(Key key) throws InvalidKeyException {
if (serviceIterator == null) {
return spi.engineTranslateKey(key);
}
Exception failure = null;
KeyFactorySpi mySpi = spi;
do {
try {
return mySpi.engineTranslateKey(key);
} catch (Exception e) {
if (failure == null) {
failure = e;
}
mySpi = nextSpi(mySpi);
}
} while (mySpi != null);
if (failure instanceof RuntimeException) {
throw (RuntimeException)failure;
}
if (failure instanceof InvalidKeyException) {
throw (InvalidKeyException)failure;
}
throw new InvalidKeyException
("Could not translate key", failure);
}
}

View file

@ -0,0 +1,142 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
import java.security.spec.KeySpec;
import java.security.spec.InvalidKeySpecException;
/**
* This class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
* for the {@code KeyFactory} class.
* All the abstract methods in this class must be implemented by each
* cryptographic service provider who wishes to supply the implementation
* of a key factory for a particular algorithm.
*
* <P> Key factories are used to convert <I>keys</I> (opaque
* cryptographic keys of type {@code Key}) into <I>key specifications</I>
* (transparent representations of the underlying key material), and vice
* versa.
*
* <P> Key factories are bi-directional. That is, they allow you to build an
* opaque key object from a given key specification (key material), or to
* retrieve the underlying key material of a key object in a suitable format.
*
* <P> Multiple compatible key specifications may exist for the same key.
* For example, a DSA public key may be specified using
* {@code DSAPublicKeySpec} or
* {@code X509EncodedKeySpec}. A key factory can be used to translate
* between compatible key specifications.
*
* <P> A provider should document all the key specifications supported by its
* key factory.
*
* @author Jan Luehe
*
*
* @see KeyFactory
* @see Key
* @see PublicKey
* @see PrivateKey
* @see java.security.spec.KeySpec
* @see java.security.spec.DSAPublicKeySpec
* @see java.security.spec.X509EncodedKeySpec
*
* @since 1.2
*/
public abstract class KeyFactorySpi {
/**
* Generates a public key object from the provided key
* specification (key material).
*
* @param keySpec the specification (key material) of the public key.
*
* @return the public key.
*
* @exception InvalidKeySpecException if the given key specification
* is inappropriate for this key factory to produce a public key.
*/
protected abstract PublicKey engineGeneratePublic(KeySpec keySpec)
throws InvalidKeySpecException;
/**
* Generates a private key object from the provided key
* specification (key material).
*
* @param keySpec the specification (key material) of the private key.
*
* @return the private key.
*
* @exception InvalidKeySpecException if the given key specification
* is inappropriate for this key factory to produce a private key.
*/
protected abstract PrivateKey engineGeneratePrivate(KeySpec keySpec)
throws InvalidKeySpecException;
/**
* Returns a specification (key material) of the given key
* object.
* {@code keySpec} identifies the specification class in which
* the key material should be returned. It could, for example, be
* {@code DSAPublicKeySpec.class}, to indicate that the
* key material should be returned in an instance of the
* {@code DSAPublicKeySpec} class.
*
* @param <T> the type of the key specification to be returned
*
* @param key the key.
*
* @param keySpec the specification class in which
* the key material should be returned.
*
* @return the underlying key specification (key material) in an instance
* of the requested specification class.
* @exception InvalidKeySpecException if the requested key specification is
* inappropriate for the given key, or the given key cannot be dealt with
* (e.g., the given key has an unrecognized format).
*/
protected abstract <T extends KeySpec>
T engineGetKeySpec(Key key, Class<T> keySpec)
throws InvalidKeySpecException;
/**
* Translates a key object, whose provider may be unknown or
* potentially untrusted, into a corresponding key object of this key
* factory.
*
* @param key the key whose provider is unknown or untrusted.
*
* @return the translated key.
*
* @exception InvalidKeyException if the given key cannot be processed
* by this key factory.
*/
protected abstract Key engineTranslateKey(Key key)
throws InvalidKeyException;
}

View file

@ -0,0 +1,100 @@
/*
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
/**
* This is the general key management exception for all operations
* dealing with key management. Examples of subclasses of
* KeyManagementException that developers might create for
* giving more detailed information could include:
*
* <ul>
* <li>KeyIDConflictException
* <li>KeyAuthorizationFailureException
* <li>ExpiredKeyException
* </ul>
*
* @author Benjamin Renaud
* @since 1.1
*
* @see Key
* @see KeyException
*/
public class KeyManagementException extends KeyException {
private static final long serialVersionUID = 947674216157062695L;
/**
* Constructs a KeyManagementException with no detail message. A
* detail message is a String that describes this particular
* exception.
*/
public KeyManagementException() {
super();
}
/**
* Constructs a KeyManagementException with the specified detail
* message. A detail message is a String that describes this
* particular exception.
*
* @param msg the detail message.
*/
public KeyManagementException(String msg) {
super(msg);
}
/**
* Creates a {@code KeyManagementException} with the specified
* detail message and cause.
*
* @param message the detail message (which is saved for later retrieval
* by the {@link #getMessage()} method).
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is permitted,
* and indicates that the cause is nonexistent or unknown.)
* @since 1.5
*/
public KeyManagementException(String message, Throwable cause) {
super(message, cause);
}
/**
* Creates a {@code KeyManagementException} with the specified cause
* and a detail message of {@code (cause==null ? null : cause.toString())}
* (which typically contains the class and detail message of
* {@code cause}).
*
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is permitted,
* and indicates that the cause is nonexistent or unknown.)
* @since 1.5
*/
public KeyManagementException(Throwable cause) {
super(cause);
}
}

View file

@ -0,0 +1,82 @@
/*
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
import java.util.*;
/**
* This class is a simple holder for a key pair (a public key and a
* private key). It does not enforce any security, and, when initialized,
* should be treated like a PrivateKey.
*
* @see PublicKey
* @see PrivateKey
*
* @author Benjamin Renaud
* @since 1.1
*/
public final class KeyPair implements java.io.Serializable {
private static final long serialVersionUID = -7565189502268009837L;
private PrivateKey privateKey;
private PublicKey publicKey;
/**
* Constructs a key pair from the given public key and private key.
*
* <p>Note that this constructor only stores references to the public
* and private key components in the generated key pair. This is safe,
* because {@code Key} objects are immutable.
*
* @param publicKey the public key.
*
* @param privateKey the private key.
*/
public KeyPair(PublicKey publicKey, PrivateKey privateKey) {
this.publicKey = publicKey;
this.privateKey = privateKey;
}
/**
* Returns a reference to the public key component of this key pair.
*
* @return a reference to the public key.
*/
public PublicKey getPublic() {
return publicKey;
}
/**
* Returns a reference to the private key component of this key pair.
*
* @return a reference to the private key.
*/
public PrivateKey getPrivate() {
return privateKey;
}
}

View file

@ -0,0 +1,740 @@
/*
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
import java.util.*;
import java.security.spec.AlgorithmParameterSpec;
import java.security.Provider.Service;
import sun.security.jca.*;
import sun.security.jca.GetInstance.Instance;
import sun.security.util.Debug;
/**
* The KeyPairGenerator class is used to generate pairs of
* public and private keys. Key pair generators are constructed using the
* {@code getInstance} factory methods (static methods that
* return instances of a given class).
*
* <p>A Key pair generator for a particular algorithm creates a public/private
* key pair that can be used with this algorithm. It also associates
* algorithm-specific parameters with each of the generated keys.
*
* <p>There are two ways to generate a key pair: in an algorithm-independent
* manner, and in an algorithm-specific manner.
* The only difference between the two is the initialization of the object:
*
* <ul>
* <li><b>Algorithm-Independent Initialization</b>
* <p>All key pair generators share the concepts of a keysize and a
* source of randomness. The keysize is interpreted differently for different
* algorithms (e.g., in the case of the <i>DSA</i> algorithm, the keysize
* corresponds to the length of the modulus).
* There is an
* {@link #initialize(int, java.security.SecureRandom) initialize}
* method in this KeyPairGenerator class that takes these two universally
* shared types of arguments. There is also one that takes just a
* {@code keysize} argument, and uses the {@code SecureRandom}
* implementation of the highest-priority installed provider as the source
* of randomness. (If none of the installed providers supply an implementation
* of {@code SecureRandom}, a system-provided source of randomness is
* used.)
*
* <p>Since no other parameters are specified when you call the above
* algorithm-independent {@code initialize} methods, it is up to the
* provider what to do about the algorithm-specific parameters (if any) to be
* associated with each of the keys.
*
* <p>If the algorithm is the <i>DSA</i> algorithm, and the keysize (modulus
* size) is 512, 768, 1024, or 2048, then the <i>Sun</i> provider uses a set of
* precomputed values for the {@code p}, {@code q}, and
* {@code g} parameters. If the modulus size is not one of the above
* values, the <i>Sun</i> provider creates a new set of parameters. Other
* providers might have precomputed parameter sets for more than just the
* modulus sizes mentioned above. Still others might not have a list of
* precomputed parameters at all and instead always create new parameter sets.
*
* <li><b>Algorithm-Specific Initialization</b>
* <p>For situations where a set of algorithm-specific parameters already
* exists (e.g., so-called <i>community parameters</i> in DSA), there are two
* {@link #initialize(java.security.spec.AlgorithmParameterSpec)
* initialize} methods that have an {@code AlgorithmParameterSpec}
* argument. One also has a {@code SecureRandom} argument, while the
* the other uses the {@code SecureRandom}
* implementation of the highest-priority installed provider as the source
* of randomness. (If none of the installed providers supply an implementation
* of {@code SecureRandom}, a system-provided source of randomness is
* used.)
* </ul>
*
* <p>In case the client does not explicitly initialize the KeyPairGenerator
* (via a call to an {@code initialize} method), each provider must
* supply (and document) a default initialization.
* See the Keysize Restriction sections of the
* {@extLink security_guide_jdk_providers JDK Providers}
* document for information on the KeyPairGenerator defaults used by
* JDK providers.
* However, note that defaults may vary across different providers.
* Additionally, the default value for a provider may change in a future
* version. Therefore, it is recommended to explicitly initialize the
* KeyPairGenerator instead of relying on provider-specific defaults.
*
* <p>Note that this class is abstract and extends from
* {@code KeyPairGeneratorSpi} for historical reasons.
* Application developers should only take notice of the methods defined in
* this {@code KeyPairGenerator} class; all the methods in
* the superclass are intended for cryptographic service providers who wish to
* supply their own implementations of key pair generators.
*
* <p> Every implementation of the Java platform is required to support the
* following standard {@code KeyPairGenerator} algorithms and keysizes in
* parentheses:
* <ul>
* <li>{@code DiffieHellman} (1024, 2048, 4096)</li>
* <li>{@code DSA} (1024, 2048)</li>
* <li>{@code RSA} (1024, 2048, 4096)</li>
* </ul>
* These algorithms are described in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#keypairgenerator-algorithms">
* KeyPairGenerator section</a> of the
* Java Security Standard Algorithm Names Specification.
* Consult the release documentation for your implementation to see if any
* other algorithms are supported.
*
* @author Benjamin Renaud
* @since 1.1
*
* @see java.security.spec.AlgorithmParameterSpec
*/
public abstract class KeyPairGenerator extends KeyPairGeneratorSpi {
private static final Debug pdebug =
Debug.getInstance("provider", "Provider");
private static final boolean skipDebug =
Debug.isOn("engine=") && !Debug.isOn("keypairgenerator");
private final String algorithm;
// The provider
Provider provider;
/**
* Creates a KeyPairGenerator object for the specified algorithm.
*
* @param algorithm the standard string name of the algorithm.
* See the KeyPairGenerator section in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#keypairgenerator-algorithms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard algorithm names.
*/
protected KeyPairGenerator(String algorithm) {
this.algorithm = algorithm;
}
/**
* Returns the standard name of the algorithm for this key pair generator.
* See the KeyPairGenerator section in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#keypairgenerator-algorithms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard algorithm names.
*
* @return the standard string name of the algorithm.
*/
public String getAlgorithm() {
return this.algorithm;
}
private static KeyPairGenerator getInstance(Instance instance,
String algorithm) {
KeyPairGenerator kpg;
if (instance.impl instanceof KeyPairGenerator) {
kpg = (KeyPairGenerator)instance.impl;
} else {
KeyPairGeneratorSpi spi = (KeyPairGeneratorSpi)instance.impl;
kpg = new Delegate(spi, algorithm);
}
kpg.provider = instance.provider;
if (!skipDebug && pdebug != null) {
pdebug.println("KeyPairGenerator." + algorithm +
" algorithm from: " + kpg.provider.getName());
}
return kpg;
}
/**
* Returns a KeyPairGenerator object that generates public/private
* key pairs for the specified algorithm.
*
* <p> This method traverses the list of registered security Providers,
* starting with the most preferred Provider.
* A new KeyPairGenerator object encapsulating the
* KeyPairGeneratorSpi implementation from the first
* Provider that supports the specified algorithm is returned.
*
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @implNote
* The JDK Reference Implementation additionally uses the
* {@code jdk.security.provider.preferred}
* {@link Security#getProperty(String) Security} property to determine
* the preferred provider order for the specified algorithm. This
* may be different than the order of providers returned by
* {@link Security#getProviders() Security.getProviders()}.
*
* @param algorithm the standard string name of the algorithm.
* See the KeyPairGenerator section in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#keypairgenerator-algorithms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard algorithm names.
*
* @return the new {@code KeyPairGenerator} object
*
* @throws NoSuchAlgorithmException if no {@code Provider} supports a
* {@code KeyPairGeneratorSpi} implementation for the
* specified algorithm
*
* @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see Provider
*/
public static KeyPairGenerator getInstance(String algorithm)
throws NoSuchAlgorithmException {
Objects.requireNonNull(algorithm, "null algorithm name");
List<Service> list =
GetInstance.getServices("KeyPairGenerator", algorithm);
Iterator<Service> t = list.iterator();
if (t.hasNext() == false) {
throw new NoSuchAlgorithmException
(algorithm + " KeyPairGenerator not available");
}
// find a working Spi or KeyPairGenerator subclass
NoSuchAlgorithmException failure = null;
do {
Service s = t.next();
try {
Instance instance =
GetInstance.getInstance(s, KeyPairGeneratorSpi.class);
if (instance.impl instanceof KeyPairGenerator) {
return getInstance(instance, algorithm);
} else {
return new Delegate(instance, t, algorithm);
}
} catch (NoSuchAlgorithmException e) {
if (failure == null) {
failure = e;
}
}
} while (t.hasNext());
throw failure;
}
/**
* Returns a KeyPairGenerator object that generates public/private
* key pairs for the specified algorithm.
*
* <p> A new KeyPairGenerator object encapsulating the
* KeyPairGeneratorSpi implementation from the specified provider
* is returned. The specified provider must be registered
* in the security provider list.
*
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param algorithm the standard string name of the algorithm.
* See the KeyPairGenerator section in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#keypairgenerator-algorithms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard algorithm names.
*
* @param provider the string name of the provider.
*
* @return the new {@code KeyPairGenerator} object
*
* @throws IllegalArgumentException if the provider name is {@code null}
* or empty
*
* @throws NoSuchAlgorithmException if a {@code KeyPairGeneratorSpi}
* implementation for the specified algorithm is not
* available from the specified provider
*
* @throws NoSuchProviderException if the specified provider is not
* registered in the security provider list
*
* @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see Provider
*/
public static KeyPairGenerator getInstance(String algorithm,
String provider)
throws NoSuchAlgorithmException, NoSuchProviderException {
Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = GetInstance.getInstance("KeyPairGenerator",
KeyPairGeneratorSpi.class, algorithm, provider);
return getInstance(instance, algorithm);
}
/**
* Returns a KeyPairGenerator object that generates public/private
* key pairs for the specified algorithm.
*
* <p> A new KeyPairGenerator object encapsulating the
* KeyPairGeneratorSpi implementation from the specified Provider
* object is returned. Note that the specified Provider object
* does not have to be registered in the provider list.
*
* @param algorithm the standard string name of the algorithm.
* See the KeyPairGenerator section in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#keypairgenerator-algorithms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard algorithm names.
*
* @param provider the provider.
*
* @return the new {@code KeyPairGenerator} object
*
* @throws IllegalArgumentException if the specified provider is
* {@code null}
*
* @throws NoSuchAlgorithmException if a {@code KeyPairGeneratorSpi}
* implementation for the specified algorithm is not available
* from the specified {@code Provider} object
*
* @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see Provider
*
* @since 1.4
*/
public static KeyPairGenerator getInstance(String algorithm,
Provider provider) throws NoSuchAlgorithmException {
Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = GetInstance.getInstance("KeyPairGenerator",
KeyPairGeneratorSpi.class, algorithm, provider);
return getInstance(instance, algorithm);
}
/**
* Returns the provider of this key pair generator object.
*
* @return the provider of this key pair generator object
*/
public final Provider getProvider() {
disableFailover();
return this.provider;
}
void disableFailover() {
// empty, overridden in Delegate
}
/**
* Initializes the key pair generator for a certain keysize using
* a default parameter set and the {@code SecureRandom}
* implementation of the highest-priority installed provider as the source
* of randomness.
* (If none of the installed providers supply an implementation of
* {@code SecureRandom}, a system-provided source of randomness is
* used.)
*
* @param keysize the keysize. This is an
* algorithm-specific metric, such as modulus length, specified in
* number of bits.
*
* @exception InvalidParameterException if the {@code keysize} is not
* supported by this KeyPairGenerator object.
*/
public void initialize(int keysize) {
initialize(keysize, JCAUtil.getSecureRandom());
}
/**
* Initializes the key pair generator for a certain keysize with
* the given source of randomness (and a default parameter set).
*
* @param keysize the keysize. This is an
* algorithm-specific metric, such as modulus length, specified in
* number of bits.
* @param random the source of randomness.
*
* @exception InvalidParameterException if the {@code keysize} is not
* supported by this KeyPairGenerator object.
*
* @since 1.2
*/
public void initialize(int keysize, SecureRandom random) {
// This does nothing, because either
// 1. the implementation object returned by getInstance() is an
// instance of KeyPairGenerator which has its own
// initialize(keysize, random) method, so the application would
// be calling that method directly, or
// 2. the implementation returned by getInstance() is an instance
// of Delegate, in which case initialize(keysize, random) is
// overridden to call the corresponding SPI method.
// (This is a special case, because the API and SPI method have the
// same name.)
}
/**
* Initializes the key pair generator using the specified parameter
* set and the {@code SecureRandom}
* implementation of the highest-priority installed provider as the source
* of randomness.
* (If none of the installed providers supply an implementation of
* {@code SecureRandom}, a system-provided source of randomness is
* used.)
*
* <p>This concrete method has been added to this previously-defined
* abstract class.
* This method calls the KeyPairGeneratorSpi
* {@link KeyPairGeneratorSpi#initialize(
* java.security.spec.AlgorithmParameterSpec,
* java.security.SecureRandom) initialize} method,
* passing it {@code params} and a source of randomness (obtained
* from the highest-priority installed provider or system-provided if none
* of the installed providers supply one).
* That {@code initialize} method always throws an
* UnsupportedOperationException if it is not overridden by the provider.
*
* @param params the parameter set used to generate the keys.
*
* @exception InvalidAlgorithmParameterException if the given parameters
* are inappropriate for this key pair generator.
*
* @since 1.2
*/
public void initialize(AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException {
initialize(params, JCAUtil.getSecureRandom());
}
/**
* Initializes the key pair generator with the given parameter
* set and source of randomness.
*
* <p>This concrete method has been added to this previously-defined
* abstract class.
* This method calls the KeyPairGeneratorSpi {@link
* KeyPairGeneratorSpi#initialize(
* java.security.spec.AlgorithmParameterSpec,
* java.security.SecureRandom) initialize} method,
* passing it {@code params} and {@code random}.
* That {@code initialize}
* method always throws an
* UnsupportedOperationException if it is not overridden by the provider.
*
* @param params the parameter set used to generate the keys.
* @param random the source of randomness.
*
* @exception InvalidAlgorithmParameterException if the given parameters
* are inappropriate for this key pair generator.
*
* @since 1.2
*/
public void initialize(AlgorithmParameterSpec params,
SecureRandom random)
throws InvalidAlgorithmParameterException
{
// This does nothing, because either
// 1. the implementation object returned by getInstance() is an
// instance of KeyPairGenerator which has its own
// initialize(params, random) method, so the application would
// be calling that method directly, or
// 2. the implementation returned by getInstance() is an instance
// of Delegate, in which case initialize(params, random) is
// overridden to call the corresponding SPI method.
// (This is a special case, because the API and SPI method have the
// same name.)
}
/**
* Generates a key pair.
*
* <p>If this KeyPairGenerator has not been initialized explicitly,
* provider-specific defaults will be used for the size and other
* (algorithm-specific) values of the generated keys.
*
* <p>This will generate a new key pair every time it is called.
*
* <p>This method is functionally equivalent to
* {@link #generateKeyPair() generateKeyPair}.
*
* @return the generated key pair
*
* @since 1.2
*/
public final KeyPair genKeyPair() {
return generateKeyPair();
}
/**
* Generates a key pair.
*
* <p>If this KeyPairGenerator has not been initialized explicitly,
* provider-specific defaults will be used for the size and other
* (algorithm-specific) values of the generated keys.
*
* <p>This will generate a new key pair every time it is called.
*
* <p>This method is functionally equivalent to
* {@link #genKeyPair() genKeyPair}.
*
* @return the generated key pair
*/
public KeyPair generateKeyPair() {
// This does nothing (except returning null), because either:
//
// 1. the implementation object returned by getInstance() is an
// instance of KeyPairGenerator which has its own implementation
// of generateKeyPair (overriding this one), so the application
// would be calling that method directly, or
//
// 2. the implementation returned by getInstance() is an instance
// of Delegate, in which case generateKeyPair is
// overridden to invoke the corresponding SPI method.
//
// (This is a special case, because in JDK 1.1.x the generateKeyPair
// method was used both as an API and a SPI method.)
return null;
}
/*
* The following class allows providers to extend from KeyPairGeneratorSpi
* rather than from KeyPairGenerator. It represents a KeyPairGenerator
* with an encapsulated, provider-supplied SPI object (of type
* KeyPairGeneratorSpi).
* If the provider implementation is an instance of KeyPairGeneratorSpi,
* the getInstance() methods above return an instance of this class, with
* the SPI object encapsulated.
*
* Note: All SPI methods from the original KeyPairGenerator class have been
* moved up the hierarchy into a new class (KeyPairGeneratorSpi), which has
* been interposed in the hierarchy between the API (KeyPairGenerator)
* and its original parent (Object).
*/
//
// error failover notes:
//
// . we failover if the implementation throws an error during init
// by retrying the init on other providers
//
// . we also failover if the init succeeded but the subsequent call
// to generateKeyPair() fails. In order for this to work, we need
// to remember the parameters to the last successful call to init
// and initialize() the next spi using them.
//
// . although not specified, KeyPairGenerators could be thread safe,
// so we make sure we do not interfere with that
//
// . failover is not available, if:
// . getInstance(algorithm, provider) was used
// . a provider extends KeyPairGenerator rather than
// KeyPairGeneratorSpi (JDK 1.1 style)
// . once getProvider() is called
//
private static final class Delegate extends KeyPairGenerator {
// The provider implementation (delegate)
private volatile KeyPairGeneratorSpi spi;
private final Object lock = new Object();
private Iterator<Service> serviceIterator;
private static final int I_NONE = 1;
private static final int I_SIZE = 2;
private static final int I_PARAMS = 3;
private int initType;
private int initKeySize;
private AlgorithmParameterSpec initParams;
private SecureRandom initRandom;
// constructor
Delegate(KeyPairGeneratorSpi spi, String algorithm) {
super(algorithm);
this.spi = spi;
}
Delegate(Instance instance, Iterator<Service> serviceIterator,
String algorithm) {
super(algorithm);
spi = (KeyPairGeneratorSpi)instance.impl;
provider = instance.provider;
this.serviceIterator = serviceIterator;
initType = I_NONE;
if (!skipDebug && pdebug != null) {
pdebug.println("KeyPairGenerator." + algorithm +
" algorithm from: " + provider.getName());
}
}
/**
* Update the active spi of this class and return the next
* implementation for failover. If no more implemenations are
* available, this method returns null. However, the active spi of
* this class is never set to null.
*/
private KeyPairGeneratorSpi nextSpi(KeyPairGeneratorSpi oldSpi,
boolean reinit) {
synchronized (lock) {
// somebody else did a failover concurrently
// try that spi now
if ((oldSpi != null) && (oldSpi != spi)) {
return spi;
}
if (serviceIterator == null) {
return null;
}
while (serviceIterator.hasNext()) {
Service s = serviceIterator.next();
try {
Object inst = s.newInstance(null);
// ignore non-spis
if (inst instanceof KeyPairGeneratorSpi == false) {
continue;
}
if (inst instanceof KeyPairGenerator) {
continue;
}
KeyPairGeneratorSpi spi = (KeyPairGeneratorSpi)inst;
if (reinit) {
if (initType == I_SIZE) {
spi.initialize(initKeySize, initRandom);
} else if (initType == I_PARAMS) {
spi.initialize(initParams, initRandom);
} else if (initType != I_NONE) {
throw new AssertionError
("KeyPairGenerator initType: " + initType);
}
}
provider = s.getProvider();
this.spi = spi;
return spi;
} catch (Exception e) {
// ignore
}
}
disableFailover();
return null;
}
}
void disableFailover() {
serviceIterator = null;
initType = 0;
initParams = null;
initRandom = null;
}
// engine method
public void initialize(int keysize, SecureRandom random) {
if (serviceIterator == null) {
spi.initialize(keysize, random);
return;
}
RuntimeException failure = null;
KeyPairGeneratorSpi mySpi = spi;
do {
try {
mySpi.initialize(keysize, random);
initType = I_SIZE;
initKeySize = keysize;
initParams = null;
initRandom = random;
return;
} catch (RuntimeException e) {
if (failure == null) {
failure = e;
}
mySpi = nextSpi(mySpi, false);
}
} while (mySpi != null);
throw failure;
}
// engine method
public void initialize(AlgorithmParameterSpec params,
SecureRandom random) throws InvalidAlgorithmParameterException {
if (serviceIterator == null) {
spi.initialize(params, random);
return;
}
Exception failure = null;
KeyPairGeneratorSpi mySpi = spi;
do {
try {
mySpi.initialize(params, random);
initType = I_PARAMS;
initKeySize = 0;
initParams = params;
initRandom = random;
return;
} catch (Exception e) {
if (failure == null) {
failure = e;
}
mySpi = nextSpi(mySpi, false);
}
} while (mySpi != null);
if (failure instanceof RuntimeException) {
throw (RuntimeException)failure;
}
// must be an InvalidAlgorithmParameterException
throw (InvalidAlgorithmParameterException)failure;
}
// engine method
public KeyPair generateKeyPair() {
if (serviceIterator == null) {
return spi.generateKeyPair();
}
RuntimeException failure = null;
KeyPairGeneratorSpi mySpi = spi;
do {
try {
return mySpi.generateKeyPair();
} catch (RuntimeException e) {
if (failure == null) {
failure = e;
}
mySpi = nextSpi(mySpi, true);
}
} while (mySpi != null);
throw failure;
}
}
}

View file

@ -0,0 +1,113 @@
/*
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
import java.security.spec.AlgorithmParameterSpec;
/**
* <p> This class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
* for the {@code KeyPairGenerator} class, which is used to generate
* pairs of public and private keys.
*
* <p> All the abstract methods in this class must be implemented by each
* cryptographic service provider who wishes to supply the implementation
* of a key pair generator for a particular algorithm.
*
* <p> In case the client does not explicitly initialize the KeyPairGenerator
* (via a call to an {@code initialize} method), each provider must
* supply (and document) a default initialization.
* See the Keysize Restriction sections of the
* {@extLink security_guide_jdk_providers JDK Providers}
* document for information on the KeyPairGenerator defaults used by
* JDK providers.
* However, note that defaults may vary across different providers.
* Additionally, the default value for a provider may change in a future
* version. Therefore, it is recommended to explicitly initialize the
* KeyPairGenerator instead of relying on provider-specific defaults.
*
* @author Benjamin Renaud
* @since 1.2
*
*
* @see KeyPairGenerator
* @see java.security.spec.AlgorithmParameterSpec
*/
public abstract class KeyPairGeneratorSpi {
/**
* Initializes the key pair generator for a certain keysize, using
* the default parameter set.
*
* @param keysize the keysize. This is an
* algorithm-specific metric, such as modulus length, specified in
* number of bits.
*
* @param random the source of randomness for this generator.
*
* @exception InvalidParameterException if the {@code keysize} is not
* supported by this KeyPairGeneratorSpi object.
*/
public abstract void initialize(int keysize, SecureRandom random);
/**
* Initializes the key pair generator using the specified parameter
* set and user-provided source of randomness.
*
* <p>This concrete method has been added to this previously-defined
* abstract class. (For backwards compatibility, it cannot be abstract.)
* It may be overridden by a provider to initialize the key pair
* generator. Such an override
* is expected to throw an InvalidAlgorithmParameterException if
* a parameter is inappropriate for this key pair generator.
* If this method is not overridden, it always throws an
* UnsupportedOperationException.
*
* @param params the parameter set used to generate the keys.
*
* @param random the source of randomness for this generator.
*
* @exception InvalidAlgorithmParameterException if the given parameters
* are inappropriate for this key pair generator.
*
* @since 1.2
*/
public void initialize(AlgorithmParameterSpec params,
SecureRandom random)
throws InvalidAlgorithmParameterException {
throw new UnsupportedOperationException();
}
/**
* Generates a key pair. Unless an initialization method is called
* using a KeyPairGenerator interface, algorithm-specific defaults
* will be used. This will generate a new key pair every time it
* is called.
*
* @return the newly generated {@code KeyPair}
*/
public abstract KeyPair generateKeyPair();
}

View file

@ -0,0 +1,192 @@
/*
* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
import java.io.*;
import java.util.Locale;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.security.spec.InvalidKeySpecException;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.SecretKeySpec;
/**
* Standardized representation for serialized Key objects.
*
* <p>
*
* Note that a serialized Key may contain sensitive information
* which should not be exposed in untrusted environments. See the
* <a href="{@docRoot}/../specs/serialization/security.html">
* Security Appendix</a>
* of the Serialization Specification for more information.
*
* @see Key
* @see KeyFactory
* @see javax.crypto.spec.SecretKeySpec
* @see java.security.spec.X509EncodedKeySpec
* @see java.security.spec.PKCS8EncodedKeySpec
*
* @since 1.5
*/
public class KeyRep implements Serializable {
private static final long serialVersionUID = -4757683898830641853L;
/**
* Key type.
*
* @since 1.5
*/
public static enum Type {
/** Type for secret keys. */
SECRET,
/** Type for public keys. */
PUBLIC,
/** Type for private keys. */
PRIVATE,
}
private static final String PKCS8 = "PKCS#8";
private static final String X509 = "X.509";
private static final String RAW = "RAW";
/**
* Either one of Type.SECRET, Type.PUBLIC, or Type.PRIVATE
*
* @serial
*/
private Type type;
/**
* The Key algorithm
*
* @serial
*/
private String algorithm;
/**
* The Key encoding format
*
* @serial
*/
private String format;
/**
* The encoded Key bytes
*
* @serial
*/
private byte[] encoded;
/**
* Construct the alternate Key class.
*
* @param type either one of Type.SECRET, Type.PUBLIC, or Type.PRIVATE
* @param algorithm the algorithm returned from
* {@code Key.getAlgorithm()}
* @param format the encoding format returned from
* {@code Key.getFormat()}
* @param encoded the encoded bytes returned from
* {@code Key.getEncoded()}
*
* @exception NullPointerException
* if type is {@code null},
* if algorithm is {@code null},
* if format is {@code null},
* or if encoded is {@code null}
*/
public KeyRep(Type type, String algorithm,
String format, byte[] encoded) {
if (type == null || algorithm == null ||
format == null || encoded == null) {
throw new NullPointerException("invalid null input(s)");
}
this.type = type;
this.algorithm = algorithm;
this.format = format.toUpperCase(Locale.ENGLISH);
this.encoded = encoded.clone();
}
/**
* Resolve the Key object.
*
* <p> This method supports three Type/format combinations:
* <ul>
* <li> Type.SECRET/"RAW" - returns a SecretKeySpec object
* constructed using encoded key bytes and algorithm
* <li> Type.PUBLIC/"X.509" - gets a KeyFactory instance for
* the key algorithm, constructs an X509EncodedKeySpec with the
* encoded key bytes, and generates a public key from the spec
* <li> Type.PRIVATE/"PKCS#8" - gets a KeyFactory instance for
* the key algorithm, constructs a PKCS8EncodedKeySpec with the
* encoded key bytes, and generates a private key from the spec
* </ul>
*
* @return the resolved Key object
*
* @exception ObjectStreamException if the Type/format
* combination is unrecognized, if the algorithm, key format, or
* encoded key bytes are unrecognized/invalid, of if the
* resolution of the key fails for any reason
*/
protected Object readResolve() throws ObjectStreamException {
try {
if (type == Type.SECRET && RAW.equals(format)) {
return new SecretKeySpec(encoded, algorithm);
} else if (type == Type.PUBLIC && X509.equals(format)) {
KeyFactory f = KeyFactory.getInstance(algorithm);
return f.generatePublic(new X509EncodedKeySpec(encoded));
} else if (type == Type.PRIVATE && PKCS8.equals(format)) {
KeyFactory f = KeyFactory.getInstance(algorithm);
return f.generatePrivate(new PKCS8EncodedKeySpec(encoded));
} else {
throw new NotSerializableException
("unrecognized type/format combination: " +
type + "/" + format);
}
} catch (NotSerializableException nse) {
throw nse;
} catch (Exception e) {
NotSerializableException nse = new NotSerializableException
("java.security.Key: " +
"[" + type + "] " +
"[" + algorithm + "] " +
"[" + format + "]");
nse.initCause(e);
throw nse;
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,90 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
/**
* This is the generic KeyStore exception.
*
* @author Jan Luehe
*
*
* @since 1.2
*/
public class KeyStoreException extends GeneralSecurityException {
private static final long serialVersionUID = -1119353179322377262L;
/**
* Constructs a KeyStoreException with no detail message. (A
* detail message is a String that describes this particular
* exception.)
*/
public KeyStoreException() {
super();
}
/**
* Constructs a KeyStoreException with the specified detail
* message. (A detail message is a String that describes this
* particular exception.)
*
* @param msg the detail message.
*/
public KeyStoreException(String msg) {
super(msg);
}
/**
* Creates a {@code KeyStoreException} with the specified
* detail message and cause.
*
* @param message the detail message (which is saved for later retrieval
* by the {@link #getMessage()} method).
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is permitted,
* and indicates that the cause is nonexistent or unknown.)
* @since 1.5
*/
public KeyStoreException(String message, Throwable cause) {
super(message, cause);
}
/**
* Creates a {@code KeyStoreException} with the specified cause
* and a detail message of {@code (cause==null ? null : cause.toString())}
* (which typically contains the class and detail message of
* {@code cause}).
*
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is permitted,
* and indicates that the cause is nonexistent or unknown.)
* @since 1.5
*/
public KeyStoreException(Throwable cause) {
super(cause);
}
}

View file

@ -0,0 +1,637 @@
/*
* Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
import java.io.*;
import java.util.*;
import java.security.KeyStore.*;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import javax.crypto.SecretKey;
import javax.security.auth.callback.*;
/**
* This class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
* for the {@code KeyStore} class.
* All the abstract methods in this class must be implemented by each
* cryptographic service provider who wishes to supply the implementation
* of a keystore for a particular keystore type.
*
* @author Jan Luehe
*
*
* @see KeyStore
*
* @since 1.2
*/
public abstract class KeyStoreSpi {
/**
* Returns the key associated with the given alias, using the given
* password to recover it. The key must have been associated with
* the alias by a call to {@code setKeyEntry},
* or by a call to {@code setEntry} with a
* {@code PrivateKeyEntry} or {@code SecretKeyEntry}.
*
* @param alias the alias name
* @param password the password for recovering the key
*
* @return the requested key, or null if the given alias does not exist
* or does not identify a key-related entry.
*
* @exception NoSuchAlgorithmException if the algorithm for recovering the
* key cannot be found
* @exception UnrecoverableKeyException if the key cannot be recovered
* (e.g., the given password is wrong).
*/
public abstract Key engineGetKey(String alias, char[] password)
throws NoSuchAlgorithmException, UnrecoverableKeyException;
/**
* Returns the certificate chain associated with the given alias.
* The certificate chain must have been associated with the alias
* by a call to {@code setKeyEntry},
* or by a call to {@code setEntry} with a
* {@code PrivateKeyEntry}.
*
* @param alias the alias name
*
* @return the certificate chain (ordered with the user's certificate first
* and the root certificate authority last), or null if the given alias
* does not exist or does not contain a certificate chain
*/
public abstract Certificate[] engineGetCertificateChain(String alias);
/**
* Returns the certificate associated with the given alias.
*
* <p> If the given alias name identifies an entry
* created by a call to {@code setCertificateEntry},
* or created by a call to {@code setEntry} with a
* {@code TrustedCertificateEntry},
* then the trusted certificate contained in that entry is returned.
*
* <p> If the given alias name identifies an entry
* created by a call to {@code setKeyEntry},
* or created by a call to {@code setEntry} with a
* {@code PrivateKeyEntry},
* then the first element of the certificate chain in that entry
* (if a chain exists) is returned.
*
* @param alias the alias name
*
* @return the certificate, or null if the given alias does not exist or
* does not contain a certificate.
*/
public abstract Certificate engineGetCertificate(String alias);
/**
* Returns the creation date of the entry identified by the given alias.
*
* @param alias the alias name
*
* @return the creation date of this entry, or null if the given alias does
* not exist
*/
public abstract Date engineGetCreationDate(String alias);
/**
* Assigns the given key to the given alias, protecting it with the given
* password.
*
* <p>If the given key is of type {@code java.security.PrivateKey},
* it must be accompanied by a certificate chain certifying the
* corresponding public key.
*
* <p>If the given alias already exists, the keystore information
* associated with it is overridden by the given key (and possibly
* certificate chain).
*
* @param alias the alias name
* @param key the key to be associated with the alias
* @param password the password to protect the key
* @param chain the certificate chain for the corresponding public
* key (only required if the given key is of type
* {@code java.security.PrivateKey}).
*
* @exception KeyStoreException if the given key cannot be protected, or
* this operation fails for some other reason
*/
public abstract void engineSetKeyEntry(String alias, Key key,
char[] password,
Certificate[] chain)
throws KeyStoreException;
/**
* Assigns the given key (that has already been protected) to the given
* alias.
*
* <p>If the protected key is of type
* {@code java.security.PrivateKey},
* it must be accompanied by a certificate chain certifying the
* corresponding public key.
*
* <p>If the given alias already exists, the keystore information
* associated with it is overridden by the given key (and possibly
* certificate chain).
*
* @param alias the alias name
* @param key the key (in protected format) to be associated with the alias
* @param chain the certificate chain for the corresponding public
* key (only useful if the protected key is of type
* {@code java.security.PrivateKey}).
*
* @exception KeyStoreException if this operation fails.
*/
public abstract void engineSetKeyEntry(String alias, byte[] key,
Certificate[] chain)
throws KeyStoreException;
/**
* Assigns the given certificate to the given alias.
*
* <p> If the given alias identifies an existing entry
* created by a call to {@code setCertificateEntry},
* or created by a call to {@code setEntry} with a
* {@code TrustedCertificateEntry},
* the trusted certificate in the existing entry
* is overridden by the given certificate.
*
* @param alias the alias name
* @param cert the certificate
*
* @exception KeyStoreException if the given alias already exists and does
* not identify an entry containing a trusted certificate,
* or this operation fails for some other reason.
*/
public abstract void engineSetCertificateEntry(String alias,
Certificate cert)
throws KeyStoreException;
/**
* Deletes the entry identified by the given alias from this keystore.
*
* @param alias the alias name
*
* @exception KeyStoreException if the entry cannot be removed.
*/
public abstract void engineDeleteEntry(String alias)
throws KeyStoreException;
/**
* Lists all the alias names of this keystore.
*
* @return enumeration of the alias names
*/
public abstract Enumeration<String> engineAliases();
/**
* Checks if the given alias exists in this keystore.
*
* @param alias the alias name
*
* @return true if the alias exists, false otherwise
*/
public abstract boolean engineContainsAlias(String alias);
/**
* Retrieves the number of entries in this keystore.
*
* @return the number of entries in this keystore
*/
public abstract int engineSize();
/**
* Returns true if the entry identified by the given alias
* was created by a call to {@code setKeyEntry},
* or created by a call to {@code setEntry} with a
* {@code PrivateKeyEntry} or a {@code SecretKeyEntry}.
*
* @param alias the alias for the keystore entry to be checked
*
* @return true if the entry identified by the given alias is a
* key-related, false otherwise.
*/
public abstract boolean engineIsKeyEntry(String alias);
/**
* Returns true if the entry identified by the given alias
* was created by a call to {@code setCertificateEntry},
* or created by a call to {@code setEntry} with a
* {@code TrustedCertificateEntry}.
*
* @param alias the alias for the keystore entry to be checked
*
* @return true if the entry identified by the given alias contains a
* trusted certificate, false otherwise.
*/
public abstract boolean engineIsCertificateEntry(String alias);
/**
* Returns the (alias) name of the first keystore entry whose certificate
* matches the given certificate.
*
* <p>This method attempts to match the given certificate with each
* keystore entry. If the entry being considered was
* created by a call to {@code setCertificateEntry},
* or created by a call to {@code setEntry} with a
* {@code TrustedCertificateEntry},
* then the given certificate is compared to that entry's certificate.
*
* <p> If the entry being considered was
* created by a call to {@code setKeyEntry},
* or created by a call to {@code setEntry} with a
* {@code PrivateKeyEntry},
* then the given certificate is compared to the first
* element of that entry's certificate chain.
*
* @param cert the certificate to match with.
*
* @return the alias name of the first entry with matching certificate,
* or null if no such entry exists in this keystore.
*/
public abstract String engineGetCertificateAlias(Certificate cert);
/**
* Stores this keystore to the given output stream, and protects its
* integrity with the given password.
*
* @param stream the output stream to which this keystore is written.
* @param password the password to generate the keystore integrity check
*
* @exception IOException if there was an I/O problem with data
* @exception NoSuchAlgorithmException if the appropriate data integrity
* algorithm could not be found
* @exception CertificateException if any of the certificates included in
* the keystore data could not be stored
*/
public abstract void engineStore(OutputStream stream, char[] password)
throws IOException, NoSuchAlgorithmException, CertificateException;
/**
* Stores this keystore using the given
* {@code KeyStore.LoadStoreParmeter}.
*
* @param param the {@code KeyStore.LoadStoreParmeter}
* that specifies how to store the keystore,
* which may be {@code null}
*
* @exception IllegalArgumentException if the given
* {@code KeyStore.LoadStoreParmeter}
* input is not recognized
* @exception IOException if there was an I/O problem with data
* @exception NoSuchAlgorithmException if the appropriate data integrity
* algorithm could not be found
* @exception CertificateException if any of the certificates included in
* the keystore data could not be stored
*
* @since 1.5
*/
public void engineStore(KeyStore.LoadStoreParameter param)
throws IOException, NoSuchAlgorithmException,
CertificateException {
throw new UnsupportedOperationException();
}
/**
* Loads the keystore from the given input stream.
*
* <p>A password may be given to unlock the keystore
* (e.g. the keystore resides on a hardware token device),
* or to check the integrity of the keystore data.
* If a password is not given for integrity checking,
* then integrity checking is not performed.
*
* @param stream the input stream from which the keystore is loaded,
* or {@code null}
* @param password the password used to check the integrity of
* the keystore, the password used to unlock the keystore,
* or {@code null}
*
* @exception IOException if there is an I/O or format problem with the
* keystore data, if a password is required but not given,
* or if the given password was incorrect. If the error is due to a
* wrong password, the {@link Throwable#getCause cause} of the
* {@code IOException} should be an
* {@code UnrecoverableKeyException}
* @exception NoSuchAlgorithmException if the algorithm used to check
* the integrity of the keystore cannot be found
* @exception CertificateException if any of the certificates in the
* keystore could not be loaded
*/
public abstract void engineLoad(InputStream stream, char[] password)
throws IOException, NoSuchAlgorithmException, CertificateException;
/**
* Loads the keystore using the given
* {@code KeyStore.LoadStoreParameter}.
*
* <p> Note that if this KeyStore has already been loaded, it is
* reinitialized and loaded again from the given parameter.
*
* @param param the {@code KeyStore.LoadStoreParameter}
* that specifies how to load the keystore,
* which may be {@code null}
*
* @implSpec
* The default implementation examines {@code KeyStore.LoadStoreParameter}
* to extract its password and pass it to
* {@link KeyStoreSpi#engineLoad(InputStream, char[])} along with a
* {@code null} {@code InputStream}.
* <p>
* If {@code KeyStore.LoadStoreParameter} is {@code null} then
* the password parameter will also be {@code null}.
* Otherwise the {@code KeyStore.ProtectionParameter} of
* {@code KeyStore.LoadStoreParameter} must be either a
* {@code KeyStore.PasswordProtection} or a
* {@code KeyStore.CallbackHandlerProtection} that supports
* {@code PasswordCallback} so that the password parameter can be
* extracted. If the {@code KeyStore.ProtectionParameter} is neither
* of those classes then a {@code NoSuchAlgorithmException} is thrown.
*
* @exception IllegalArgumentException if the given
* {@code KeyStore.LoadStoreParameter}
* input is not recognized
* @exception IOException if there is an I/O or format problem with the
* keystore data. If the error is due to an incorrect
* {@code ProtectionParameter} (e.g. wrong password)
* the {@link Throwable#getCause cause} of the
* {@code IOException} should be an
* {@code UnrecoverableKeyException}
* @exception NoSuchAlgorithmException if the algorithm used to check
* the integrity of the keystore cannot be found
* @exception CertificateException if any of the certificates in the
* keystore could not be loaded
*
* @since 1.5
*/
public void engineLoad(KeyStore.LoadStoreParameter param)
throws IOException, NoSuchAlgorithmException,
CertificateException {
if (param == null) {
engineLoad((InputStream)null, (char[])null);
return;
}
ProtectionParameter protection = param.getProtectionParameter();
char[] password;
if (protection instanceof PasswordProtection) {
password = ((PasswordProtection)protection).getPassword();
} else if (protection instanceof CallbackHandlerProtection) {
CallbackHandler handler =
((CallbackHandlerProtection)protection).getCallbackHandler();
PasswordCallback callback =
new PasswordCallback("Password: ", false);
try {
handler.handle(new Callback[] {callback});
} catch (UnsupportedCallbackException e) {
throw new NoSuchAlgorithmException
("Could not obtain password", e);
}
password = callback.getPassword();
callback.clearPassword();
if (password == null) {
throw new NoSuchAlgorithmException("No password provided");
}
} else {
throw new NoSuchAlgorithmException("ProtectionParameter must"
+ " be PasswordProtection or CallbackHandlerProtection");
}
engineLoad(null, password);
return;
}
/**
* Gets a {@code KeyStore.Entry} for the specified alias
* with the specified protection parameter.
*
* @param alias get the {@code KeyStore.Entry} for this alias
* @param protParam the {@code ProtectionParameter}
* used to protect the {@code Entry},
* which may be {@code null}
*
* @return the {@code KeyStore.Entry} for the specified alias,
* or {@code null} if there is no such entry
*
* @exception KeyStoreException if the operation failed
* @exception NoSuchAlgorithmException if the algorithm for recovering the
* entry cannot be found
* @exception UnrecoverableEntryException if the specified
* {@code protParam} were insufficient or invalid
* @exception UnrecoverableKeyException if the entry is a
* {@code PrivateKeyEntry} or {@code SecretKeyEntry}
* and the specified {@code protParam} does not contain
* the information needed to recover the key (e.g. wrong password)
*
* @since 1.5
*/
public KeyStore.Entry engineGetEntry(String alias,
KeyStore.ProtectionParameter protParam)
throws KeyStoreException, NoSuchAlgorithmException,
UnrecoverableEntryException {
if (!engineContainsAlias(alias)) {
return null;
}
if (protParam == null) {
if (engineIsCertificateEntry(alias)) {
return new KeyStore.TrustedCertificateEntry
(engineGetCertificate(alias));
} else {
throw new UnrecoverableKeyException
("requested entry requires a password");
}
}
if (protParam instanceof KeyStore.PasswordProtection) {
if (engineIsCertificateEntry(alias)) {
throw new UnsupportedOperationException
("trusted certificate entries are not password-protected");
} else if (engineIsKeyEntry(alias)) {
KeyStore.PasswordProtection pp =
(KeyStore.PasswordProtection)protParam;
if (pp.getProtectionAlgorithm() != null) {
throw new KeyStoreException(
"unsupported password protection algorithm");
}
char[] password = pp.getPassword();
Key key = engineGetKey(alias, password);
if (key instanceof PrivateKey) {
Certificate[] chain = engineGetCertificateChain(alias);
return new KeyStore.PrivateKeyEntry((PrivateKey)key, chain);
} else if (key instanceof SecretKey) {
return new KeyStore.SecretKeyEntry((SecretKey)key);
}
}
}
throw new UnsupportedOperationException();
}
/**
* Saves a {@code KeyStore.Entry} under the specified alias.
* The specified protection parameter is used to protect the
* {@code Entry}.
*
* <p> If an entry already exists for the specified alias,
* it is overridden.
*
* @param alias save the {@code KeyStore.Entry} under this alias
* @param entry the {@code Entry} to save
* @param protParam the {@code ProtectionParameter}
* used to protect the {@code Entry},
* which may be {@code null}
*
* @exception KeyStoreException if this operation fails
*
* @since 1.5
*/
public void engineSetEntry(String alias, KeyStore.Entry entry,
KeyStore.ProtectionParameter protParam)
throws KeyStoreException {
// get password
if (protParam != null &&
!(protParam instanceof KeyStore.PasswordProtection)) {
throw new KeyStoreException("unsupported protection parameter");
}
KeyStore.PasswordProtection pProtect = null;
if (protParam != null) {
pProtect = (KeyStore.PasswordProtection)protParam;
if (pProtect.getProtectionAlgorithm() != null) {
throw new KeyStoreException(
"unsupported password protection algorithm");
}
}
// set entry
if (entry instanceof KeyStore.TrustedCertificateEntry) {
if (protParam != null && pProtect.getPassword() != null) {
// pre-1.5 style setCertificateEntry did not allow password
throw new KeyStoreException
("trusted certificate entries are not password-protected");
} else {
KeyStore.TrustedCertificateEntry tce =
(KeyStore.TrustedCertificateEntry)entry;
engineSetCertificateEntry(alias, tce.getTrustedCertificate());
return;
}
} else if (entry instanceof KeyStore.PrivateKeyEntry) {
if (pProtect == null || pProtect.getPassword() == null) {
// pre-1.5 style setKeyEntry required password
throw new KeyStoreException
("non-null password required to create PrivateKeyEntry");
} else {
engineSetKeyEntry
(alias,
((KeyStore.PrivateKeyEntry)entry).getPrivateKey(),
pProtect.getPassword(),
((KeyStore.PrivateKeyEntry)entry).getCertificateChain());
return;
}
} else if (entry instanceof KeyStore.SecretKeyEntry) {
if (pProtect == null || pProtect.getPassword() == null) {
// pre-1.5 style setKeyEntry required password
throw new KeyStoreException
("non-null password required to create SecretKeyEntry");
} else {
engineSetKeyEntry
(alias,
((KeyStore.SecretKeyEntry)entry).getSecretKey(),
pProtect.getPassword(),
(Certificate[])null);
return;
}
}
throw new KeyStoreException
("unsupported entry type: " + entry.getClass().getName());
}
/**
* Determines if the keystore {@code Entry} for the specified
* {@code alias} is an instance or subclass of the specified
* {@code entryClass}.
*
* @param alias the alias name
* @param entryClass the entry class
*
* @return true if the keystore {@code Entry} for the specified
* {@code alias} is an instance or subclass of the
* specified {@code entryClass}, false otherwise
*
* @since 1.5
*/
public boolean
engineEntryInstanceOf(String alias,
Class<? extends KeyStore.Entry> entryClass)
{
if (entryClass == KeyStore.TrustedCertificateEntry.class) {
return engineIsCertificateEntry(alias);
}
if (entryClass == KeyStore.PrivateKeyEntry.class) {
return engineIsKeyEntry(alias) &&
engineGetCertificate(alias) != null;
}
if (entryClass == KeyStore.SecretKeyEntry.class) {
return engineIsKeyEntry(alias) &&
engineGetCertificate(alias) == null;
}
return false;
}
/**
* Probes the specified input stream to determine whether it contains a
* keystore that is supported by this implementation, or not.
*
* @implSpec
* This method returns false by default. Keystore implementations should
* override this method to peek at the data stream directly or to use other
* content detection mechanisms.
*
* @param stream the keystore data to be probed
*
* @return true if the keystore data is supported, otherwise false
*
* @throws IOException if there is an I/O problem with the keystore data.
* @throws NullPointerException if stream is {@code null}.
*
* @since 9
*/
public boolean engineProbe(InputStream stream) throws IOException {
if (stream == null) {
throw new NullPointerException("input stream must not be null");
}
return false;
}
}

View file

@ -0,0 +1,641 @@
/*
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
import java.util.*;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.nio.ByteBuffer;
import sun.security.util.Debug;
import sun.security.util.MessageDigestSpi2;
import javax.crypto.SecretKey;
/**
* This MessageDigest class provides applications the functionality of a
* message digest algorithm, such as SHA-1 or SHA-256.
* Message digests are secure one-way hash functions that take arbitrary-sized
* data and output a fixed-length hash value.
*
* <p>A MessageDigest object starts out initialized. The data is
* processed through it using the {@link #update(byte) update}
* methods. At any point {@link #reset() reset} can be called
* to reset the digest. Once all the data to be updated has been
* updated, one of the {@link #digest() digest} methods should
* be called to complete the hash computation.
*
* <p>The {@code digest} method can be called once for a given number
* of updates. After {@code digest} has been called, the MessageDigest
* object is reset to its initialized state.
*
* <p>Implementations are free to implement the Cloneable interface.
* Client applications can test cloneability by attempting cloning
* and catching the CloneNotSupportedException:
*
* <pre>{@code
* MessageDigest md = MessageDigest.getInstance("SHA-256");
*
* try {
* md.update(toChapter1);
* MessageDigest tc1 = md.clone();
* byte[] toChapter1Digest = tc1.digest();
* md.update(toChapter2);
* ...etc.
* } catch (CloneNotSupportedException cnse) {
* throw new DigestException("couldn't make digest of partial content");
* }
* }</pre>
*
* <p>Note that if a given implementation is not cloneable, it is
* still possible to compute intermediate digests by instantiating
* several instances, if the number of digests is known in advance.
*
* <p>Note that this class is abstract and extends from
* {@code MessageDigestSpi} for historical reasons.
* Application developers should only take notice of the methods defined in
* this {@code MessageDigest} class; all the methods in
* the superclass are intended for cryptographic service providers who wish to
* supply their own implementations of message digest algorithms.
*
* <p> Every implementation of the Java platform is required to support
* the following standard {@code MessageDigest} algorithms:
* <ul>
* <li>{@code MD5}</li>
* <li>{@code SHA-1}</li>
* <li>{@code SHA-256}</li>
* </ul>
* These algorithms are described in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#messagedigest-algorithms">
* MessageDigest section</a> of the
* Java Security Standard Algorithm Names Specification.
* Consult the release documentation for your implementation to see if any
* other algorithms are supported.
*
* @author Benjamin Renaud
* @since 1.1
*
* @see DigestInputStream
* @see DigestOutputStream
*/
public abstract class MessageDigest extends MessageDigestSpi {
private static final Debug pdebug =
Debug.getInstance("provider", "Provider");
private static final boolean skipDebug =
Debug.isOn("engine=") && !Debug.isOn("messagedigest");
private String algorithm;
// The state of this digest
private static final int INITIAL = 0;
private static final int IN_PROGRESS = 1;
private int state = INITIAL;
// The provider
private Provider provider;
/**
* Creates a message digest with the specified algorithm name.
*
* @param algorithm the standard name of the digest algorithm.
* See the MessageDigest section in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#messagedigest-algorithms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard algorithm names.
*/
protected MessageDigest(String algorithm) {
this.algorithm = algorithm;
}
/**
* Returns a MessageDigest object that implements the specified digest
* algorithm.
*
* <p> This method traverses the list of registered security Providers,
* starting with the most preferred Provider.
* A new MessageDigest object encapsulating the
* MessageDigestSpi implementation from the first
* Provider that supports the specified algorithm is returned.
*
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @implNote
* The JDK Reference Implementation additionally uses the
* {@code jdk.security.provider.preferred}
* {@link Security#getProperty(String) Security} property to determine
* the preferred provider order for the specified algorithm. This
* may be different than the order of providers returned by
* {@link Security#getProviders() Security.getProviders()}.
*
* @param algorithm the name of the algorithm requested.
* See the MessageDigest section in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#messagedigest-algorithms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard algorithm names.
*
* @return a {@code MessageDigest} object that implements the
* specified algorithm
*
* @throws NoSuchAlgorithmException if no {@code Provider} supports a
* {@code MessageDigestSpi} implementation for the
* specified algorithm
*
* @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see Provider
*/
public static MessageDigest getInstance(String algorithm)
throws NoSuchAlgorithmException {
Objects.requireNonNull(algorithm, "null algorithm name");
try {
MessageDigest md;
Object[] objs = Security.getImpl(algorithm, "MessageDigest",
(String)null);
if (objs[0] instanceof MessageDigest) {
md = (MessageDigest)objs[0];
} else {
md = new Delegate((MessageDigestSpi)objs[0], algorithm);
}
md.provider = (Provider)objs[1];
if (!skipDebug && pdebug != null) {
pdebug.println("MessageDigest." + algorithm +
" algorithm from: " + md.provider.getName());
}
return md;
} catch(NoSuchProviderException e) {
throw new NoSuchAlgorithmException(algorithm + " not found");
}
}
/**
* Returns a MessageDigest object that implements the specified digest
* algorithm.
*
* <p> A new MessageDigest object encapsulating the
* MessageDigestSpi implementation from the specified provider
* is returned. The specified provider must be registered
* in the security provider list.
*
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param algorithm the name of the algorithm requested.
* See the MessageDigest section in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#messagedigest-algorithms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard algorithm names.
*
* @param provider the name of the provider.
*
* @return a {@code MessageDigest} object that implements the
* specified algorithm
*
* @throws IllegalArgumentException if the provider name is {@code null}
* or empty
*
* @throws NoSuchAlgorithmException if a {@code MessageDigestSpi}
* implementation for the specified algorithm is not
* available from the specified provider
*
* @throws NoSuchProviderException if the specified provider is not
* registered in the security provider list
*
* @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see Provider
*/
public static MessageDigest getInstance(String algorithm, String provider)
throws NoSuchAlgorithmException, NoSuchProviderException
{
Objects.requireNonNull(algorithm, "null algorithm name");
if (provider == null || provider.length() == 0)
throw new IllegalArgumentException("missing provider");
Object[] objs = Security.getImpl(algorithm, "MessageDigest", provider);
if (objs[0] instanceof MessageDigest) {
MessageDigest md = (MessageDigest)objs[0];
md.provider = (Provider)objs[1];
return md;
} else {
MessageDigest delegate =
new Delegate((MessageDigestSpi)objs[0], algorithm);
delegate.provider = (Provider)objs[1];
return delegate;
}
}
/**
* Returns a MessageDigest object that implements the specified digest
* algorithm.
*
* <p> A new MessageDigest object encapsulating the
* MessageDigestSpi implementation from the specified Provider
* object is returned. Note that the specified Provider object
* does not have to be registered in the provider list.
*
* @param algorithm the name of the algorithm requested.
* See the MessageDigest section in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#messagedigest-algorithms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard algorithm names.
*
* @param provider the provider.
*
* @return a {@code MessageDigest} object that implements the
* specified algorithm
*
* @throws IllegalArgumentException if the specified provider is
* {@code null}
*
* @throws NoSuchAlgorithmException if a {@code MessageDigestSpi}
* implementation for the specified algorithm is not available
* from the specified {@code Provider} object
*
* @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see Provider
*
* @since 1.4
*/
public static MessageDigest getInstance(String algorithm,
Provider provider)
throws NoSuchAlgorithmException
{
Objects.requireNonNull(algorithm, "null algorithm name");
if (provider == null)
throw new IllegalArgumentException("missing provider");
Object[] objs = Security.getImpl(algorithm, "MessageDigest", provider);
if (objs[0] instanceof MessageDigest) {
MessageDigest md = (MessageDigest)objs[0];
md.provider = (Provider)objs[1];
return md;
} else {
MessageDigest delegate =
new Delegate((MessageDigestSpi)objs[0], algorithm);
delegate.provider = (Provider)objs[1];
return delegate;
}
}
/**
* Returns the provider of this message digest object.
*
* @return the provider of this message digest object
*/
public final Provider getProvider() {
return this.provider;
}
/**
* Updates the digest using the specified byte.
*
* @param input the byte with which to update the digest.
*/
public void update(byte input) {
engineUpdate(input);
state = IN_PROGRESS;
}
/**
* Updates the digest using the specified array of bytes, starting
* at the specified offset.
*
* @param input the array of bytes.
*
* @param offset the offset to start from in the array of bytes.
*
* @param len the number of bytes to use, starting at
* {@code offset}.
*/
public void update(byte[] input, int offset, int len) {
if (input == null) {
throw new IllegalArgumentException("No input buffer given");
}
if (input.length - offset < len) {
throw new IllegalArgumentException("Input buffer too short");
}
engineUpdate(input, offset, len);
state = IN_PROGRESS;
}
/**
* Updates the digest using the specified array of bytes.
*
* @param input the array of bytes.
*/
public void update(byte[] input) {
engineUpdate(input, 0, input.length);
state = IN_PROGRESS;
}
/**
* Update the digest using the specified ByteBuffer. The digest is
* updated using the {@code input.remaining()} bytes starting
* at {@code input.position()}.
* Upon return, the buffer's position will be equal to its limit;
* its limit will not have changed.
*
* @param input the ByteBuffer
* @since 1.5
*/
public final void update(ByteBuffer input) {
if (input == null) {
throw new NullPointerException();
}
engineUpdate(input);
state = IN_PROGRESS;
}
/**
* Completes the hash computation by performing final operations
* such as padding. The digest is reset after this call is made.
*
* @return the array of bytes for the resulting hash value.
*/
public byte[] digest() {
/* Resetting is the responsibility of implementors. */
byte[] result = engineDigest();
state = INITIAL;
return result;
}
/**
* Completes the hash computation by performing final operations
* such as padding. The digest is reset after this call is made.
*
* @param buf output buffer for the computed digest
*
* @param offset offset into the output buffer to begin storing the digest
*
* @param len number of bytes within buf allotted for the digest
*
* @return the number of bytes placed into {@code buf}
*
* @exception DigestException if an error occurs.
*/
public int digest(byte[] buf, int offset, int len) throws DigestException {
if (buf == null) {
throw new IllegalArgumentException("No output buffer given");
}
if (buf.length - offset < len) {
throw new IllegalArgumentException
("Output buffer too small for specified offset and length");
}
int numBytes = engineDigest(buf, offset, len);
state = INITIAL;
return numBytes;
}
/**
* Performs a final update on the digest using the specified array
* of bytes, then completes the digest computation. That is, this
* method first calls {@link #update(byte[]) update(input)},
* passing the <i>input</i> array to the {@code update} method,
* then calls {@link #digest() digest()}.
*
* @param input the input to be updated before the digest is
* completed.
*
* @return the array of bytes for the resulting hash value.
*/
public byte[] digest(byte[] input) {
update(input);
return digest();
}
private String getProviderName() {
return (provider == null) ? "(no provider)" : provider.getName();
}
/**
* Returns a string representation of this message digest object.
*/
public String toString() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream p = new PrintStream(baos);
p.print(algorithm+" Message Digest from "+getProviderName()+", ");
switch (state) {
case INITIAL:
p.print("<initialized>");
break;
case IN_PROGRESS:
p.print("<in progress>");
break;
}
p.println();
return (baos.toString());
}
/**
* Compares two digests for equality. Two digests are equal if they have
* the same length and all bytes at corresponding positions are equal.
*
* @implNote
* If the digests are the same length, all bytes are examined to
* determine equality.
*
* @param digesta one of the digests to compare.
*
* @param digestb the other digest to compare.
*
* @return true if the digests are equal, false otherwise.
*/
public static boolean isEqual(byte[] digesta, byte[] digestb) {
if (digesta == digestb) return true;
if (digesta == null || digestb == null) {
return false;
}
if (digesta.length != digestb.length) {
return false;
}
int result = 0;
// time-constant comparison
for (int i = 0; i < digesta.length; i++) {
result |= digesta[i] ^ digestb[i];
}
return result == 0;
}
/**
* Resets the digest for further use.
*/
public void reset() {
engineReset();
state = INITIAL;
}
/**
* Returns a string that identifies the algorithm, independent of
* implementation details. The name should be a standard
* Java Security name (such as "SHA-256").
* See the MessageDigest section in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#messagedigest-algorithms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard algorithm names.
*
* @return the name of the algorithm
*/
public final String getAlgorithm() {
return this.algorithm;
}
/**
* Returns the length of the digest in bytes, or 0 if this operation is
* not supported by the provider and the implementation is not cloneable.
*
* @return the digest length in bytes, or 0 if this operation is not
* supported by the provider and the implementation is not cloneable.
*
* @since 1.2
*/
public final int getDigestLength() {
int digestLen = engineGetDigestLength();
if (digestLen == 0) {
try {
MessageDigest md = (MessageDigest)clone();
byte[] digest = md.digest();
return digest.length;
} catch (CloneNotSupportedException e) {
return digestLen;
}
}
return digestLen;
}
/**
* Returns a clone if the implementation is cloneable.
*
* @return a clone if the implementation is cloneable.
*
* @exception CloneNotSupportedException if this is called on an
* implementation that does not support {@code Cloneable}.
*/
public Object clone() throws CloneNotSupportedException {
if (this instanceof Cloneable) {
return super.clone();
} else {
throw new CloneNotSupportedException();
}
}
/*
* The following class allows providers to extend from MessageDigestSpi
* rather than from MessageDigest. It represents a MessageDigest with an
* encapsulated, provider-supplied SPI object (of type MessageDigestSpi).
* If the provider implementation is an instance of MessageDigestSpi,
* the getInstance() methods above return an instance of this class, with
* the SPI object encapsulated.
*
* Note: All SPI methods from the original MessageDigest class have been
* moved up the hierarchy into a new class (MessageDigestSpi), which has
* been interposed in the hierarchy between the API (MessageDigest)
* and its original parent (Object).
*/
static class Delegate extends MessageDigest implements MessageDigestSpi2 {
// The provider implementation (delegate)
private MessageDigestSpi digestSpi;
// constructor
public Delegate(MessageDigestSpi digestSpi, String algorithm) {
super(algorithm);
this.digestSpi = digestSpi;
}
/**
* Returns a clone if the delegate is cloneable.
*
* @return a clone if the delegate is cloneable.
*
* @exception CloneNotSupportedException if this is called on a
* delegate that does not support {@code Cloneable}.
*/
public Object clone() throws CloneNotSupportedException {
if (digestSpi instanceof Cloneable) {
MessageDigestSpi digestSpiClone =
(MessageDigestSpi)digestSpi.clone();
// Because 'algorithm', 'provider', and 'state' are private
// members of our supertype, we must perform a cast to
// access them.
MessageDigest that =
new Delegate(digestSpiClone,
((MessageDigest)this).algorithm);
that.provider = ((MessageDigest)this).provider;
that.state = ((MessageDigest)this).state;
return that;
} else {
throw new CloneNotSupportedException();
}
}
protected int engineGetDigestLength() {
return digestSpi.engineGetDigestLength();
}
protected void engineUpdate(byte input) {
digestSpi.engineUpdate(input);
}
protected void engineUpdate(byte[] input, int offset, int len) {
digestSpi.engineUpdate(input, offset, len);
}
protected void engineUpdate(ByteBuffer input) {
digestSpi.engineUpdate(input);
}
public void engineUpdate(SecretKey key) throws InvalidKeyException {
if (digestSpi instanceof MessageDigestSpi2) {
((MessageDigestSpi2)digestSpi).engineUpdate(key);
} else {
throw new UnsupportedOperationException
("Digest does not support update of SecretKey object");
}
}
protected byte[] engineDigest() {
return digestSpi.engineDigest();
}
protected int engineDigest(byte[] buf, int offset, int len)
throws DigestException {
return digestSpi.engineDigest(buf, offset, len);
}
protected void engineReset() {
digestSpi.engineReset();
}
}
}

View file

@ -0,0 +1,207 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
import java.nio.ByteBuffer;
import sun.security.jca.JCAUtil;
/**
* This class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
* for the {@code MessageDigest} class, which provides the functionality
* of a message digest algorithm, such as MD5 or SHA. Message digests are
* secure one-way hash functions that take arbitrary-sized data and output a
* fixed-length hash value.
*
* <p> All the abstract methods in this class must be implemented by a
* cryptographic service provider who wishes to supply the implementation
* of a particular message digest algorithm.
*
* <p> Implementations are free to implement the Cloneable interface.
*
* @author Benjamin Renaud
* @since 1.2
*
*
* @see MessageDigest
*/
public abstract class MessageDigestSpi {
// for re-use in engineUpdate(ByteBuffer input)
private byte[] tempArray;
/**
* Returns the digest length in bytes.
*
* <p>This concrete method has been added to this previously-defined
* abstract class. (For backwards compatibility, it cannot be abstract.)
*
* <p>The default behavior is to return 0.
*
* <p>This method may be overridden by a provider to return the digest
* length.
*
* @return the digest length in bytes.
*
* @since 1.2
*/
protected int engineGetDigestLength() {
return 0;
}
/**
* Updates the digest using the specified byte.
*
* @param input the byte to use for the update.
*/
protected abstract void engineUpdate(byte input);
/**
* Updates the digest using the specified array of bytes,
* starting at the specified offset.
*
* @param input the array of bytes to use for the update.
*
* @param offset the offset to start from in the array of bytes.
*
* @param len the number of bytes to use, starting at
* {@code offset}.
*/
protected abstract void engineUpdate(byte[] input, int offset, int len);
/**
* Update the digest using the specified ByteBuffer. The digest is
* updated using the {@code input.remaining()} bytes starting
* at {@code input.position()}.
* Upon return, the buffer's position will be equal to its limit;
* its limit will not have changed.
*
* @param input the ByteBuffer
* @since 1.5
*/
protected void engineUpdate(ByteBuffer input) {
if (input.hasRemaining() == false) {
return;
}
if (input.hasArray()) {
byte[] b = input.array();
int ofs = input.arrayOffset();
int pos = input.position();
int lim = input.limit();
engineUpdate(b, ofs + pos, lim - pos);
input.position(lim);
} else {
int len = input.remaining();
int n = JCAUtil.getTempArraySize(len);
if ((tempArray == null) || (n > tempArray.length)) {
tempArray = new byte[n];
}
while (len > 0) {
int chunk = Math.min(len, tempArray.length);
input.get(tempArray, 0, chunk);
engineUpdate(tempArray, 0, chunk);
len -= chunk;
}
}
}
/**
* Completes the hash computation by performing final
* operations such as padding. Once {@code engineDigest} has
* been called, the engine should be reset (see
* {@link #engineReset() engineReset}).
* Resetting is the responsibility of the
* engine implementor.
*
* @return the array of bytes for the resulting hash value.
*/
protected abstract byte[] engineDigest();
/**
* Completes the hash computation by performing final
* operations such as padding. Once {@code engineDigest} has
* been called, the engine should be reset (see
* {@link #engineReset() engineReset}).
* Resetting is the responsibility of the
* engine implementor.
*
* This method should be abstract, but we leave it concrete for
* binary compatibility. Knowledgeable providers should override this
* method.
*
* @param buf the output buffer in which to store the digest
*
* @param offset offset to start from in the output buffer
*
* @param len number of bytes within buf allotted for the digest.
* Both this default implementation and the SUN provider do not
* return partial digests. The presence of this parameter is solely
* for consistency in our API's. If the value of this parameter is less
* than the actual digest length, the method will throw a DigestException.
* This parameter is ignored if its value is greater than or equal to
* the actual digest length.
*
* @return the length of the digest stored in the output buffer.
*
* @exception DigestException if an error occurs.
*
* @since 1.2
*/
protected int engineDigest(byte[] buf, int offset, int len)
throws DigestException {
byte[] digest = engineDigest();
if (len < digest.length)
throw new DigestException("partial digests not returned");
if (buf.length - offset < digest.length)
throw new DigestException("insufficient space in the output "
+ "buffer to store the digest");
System.arraycopy(digest, 0, buf, offset, digest.length);
return digest.length;
}
/**
* Resets the digest for further use.
*/
protected abstract void engineReset();
/**
* Returns a clone if the implementation is cloneable.
*
* @return a clone if the implementation is cloneable.
*
* @exception CloneNotSupportedException if this is called on an
* implementation that does not support {@code Cloneable}.
*/
public Object clone() throws CloneNotSupportedException {
if (this instanceof Cloneable) {
return super.clone();
} else {
throw new CloneNotSupportedException();
}
}
}

View file

@ -0,0 +1,90 @@
/*
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
/**
* This exception is thrown when a particular cryptographic algorithm is
* requested but is not available in the environment.
*
* @author Benjamin Renaud
* @since 1.1
*/
public class NoSuchAlgorithmException extends GeneralSecurityException {
private static final long serialVersionUID = -7443947487218346562L;
/**
* Constructs a NoSuchAlgorithmException with no detail
* message. A detail message is a String that describes this
* particular exception.
*/
public NoSuchAlgorithmException() {
super();
}
/**
* Constructs a NoSuchAlgorithmException with the specified
* detail message. A detail message is a String that describes
* this particular exception, which may, for example, specify which
* algorithm is not available.
*
* @param msg the detail message.
*/
public NoSuchAlgorithmException(String msg) {
super(msg);
}
/**
* Creates a {@code NoSuchAlgorithmException} with the specified
* detail message and cause.
*
* @param message the detail message (which is saved for later retrieval
* by the {@link #getMessage()} method).
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is permitted,
* and indicates that the cause is nonexistent or unknown.)
* @since 1.5
*/
public NoSuchAlgorithmException(String message, Throwable cause) {
super(message, cause);
}
/**
* Creates a {@code NoSuchAlgorithmException} with the specified cause
* and a detail message of {@code (cause==null ? null : cause.toString())}
* (which typically contains the class and detail message of
* {@code cause}).
*
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is permitted,
* and indicates that the cause is nonexistent or unknown.)
* @since 1.5
*/
public NoSuchAlgorithmException(Throwable cause) {
super(cause);
}
}

View file

@ -0,0 +1,59 @@
/*
* Copyright (c) 1996, 2003, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
/**
* This exception is thrown when a particular security provider is
* requested but is not available in the environment.
*
* @author Benjamin Renaud
* @since 1.1
*/
public class NoSuchProviderException extends GeneralSecurityException {
private static final long serialVersionUID = 8488111756688534474L;
/**
* Constructs a NoSuchProviderException with no detail message. A
* detail message is a String that describes this particular
* exception.
*/
public NoSuchProviderException() {
super();
}
/**
* Constructs a NoSuchProviderException with the specified detail
* message. A detail message is a String that describes this
* particular exception.
*
* @param msg the detail message.
*/
public NoSuchProviderException(String msg) {
super(msg);
}
}

View file

@ -0,0 +1,286 @@
/*
* Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
import java.io.IOException;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.regex.Pattern;
import sun.security.util.*;
/**
* An attribute associated with a PKCS12 keystore entry.
* The attribute name is an ASN.1 Object Identifier and the attribute
* value is a set of ASN.1 types.
*
* @since 1.8
*/
public final class PKCS12Attribute implements KeyStore.Entry.Attribute {
private static final Pattern COLON_SEPARATED_HEX_PAIRS =
Pattern.compile("^[0-9a-fA-F]{2}(:[0-9a-fA-F]{2})+$");
private String name;
private String value;
private byte[] encoded;
private int hashValue = -1;
/**
* Constructs a PKCS12 attribute from its name and value.
* The name is an ASN.1 Object Identifier represented as a list of
* dot-separated integers.
* A string value is represented as the string itself.
* A binary value is represented as a string of colon-separated
* pairs of hexadecimal digits.
* Multi-valued attributes are represented as a comma-separated
* list of values, enclosed in square brackets. See
* {@link Arrays#toString(java.lang.Object[])}.
* <p>
* A string value will be DER-encoded as an ASN.1 UTF8String and a
* binary value will be DER-encoded as an ASN.1 Octet String.
*
* @param name the attribute's identifier
* @param value the attribute's value
*
* @exception NullPointerException if {@code name} or {@code value}
* is {@code null}
* @exception IllegalArgumentException if {@code name} or
* {@code value} is incorrectly formatted
*/
public PKCS12Attribute(String name, String value) {
if (name == null || value == null) {
throw new NullPointerException();
}
// Validate name
ObjectIdentifier type;
try {
type = new ObjectIdentifier(name);
} catch (IOException e) {
throw new IllegalArgumentException("Incorrect format: name", e);
}
this.name = name;
// Validate value
int length = value.length();
String[] values;
if (length > 1 &&
value.charAt(0) == '[' && value.charAt(length - 1) == ']') {
values = value.substring(1, length - 1).split(", ");
} else {
values = new String[]{ value };
}
this.value = value;
try {
this.encoded = encode(type, values);
} catch (IOException e) {
throw new IllegalArgumentException("Incorrect format: value", e);
}
}
/**
* Constructs a PKCS12 attribute from its ASN.1 DER encoding.
* The DER encoding is specified by the following ASN.1 definition:
* <pre>
*
* Attribute ::= SEQUENCE {
* type AttributeType,
* values SET OF AttributeValue
* }
* AttributeType ::= OBJECT IDENTIFIER
* AttributeValue ::= ANY defined by type
*
* </pre>
*
* @param encoded the attribute's ASN.1 DER encoding. It is cloned
* to prevent subsequent modificaion.
*
* @exception NullPointerException if {@code encoded} is
* {@code null}
* @exception IllegalArgumentException if {@code encoded} is
* incorrectly formatted
*/
public PKCS12Attribute(byte[] encoded) {
if (encoded == null) {
throw new NullPointerException();
}
this.encoded = encoded.clone();
try {
parse(encoded);
} catch (IOException e) {
throw new IllegalArgumentException("Incorrect format: encoded", e);
}
}
/**
* Returns the attribute's ASN.1 Object Identifier represented as a
* list of dot-separated integers.
*
* @return the attribute's identifier
*/
@Override
public String getName() {
return name;
}
/**
* Returns the attribute's ASN.1 DER-encoded value as a string.
* An ASN.1 DER-encoded value is returned in one of the following
* {@code String} formats:
* <ul>
* <li> the DER encoding of a basic ASN.1 type that has a natural
* string representation is returned as the string itself.
* Such types are currently limited to BOOLEAN, INTEGER,
* OBJECT IDENTIFIER, UTCTime, GeneralizedTime and the
* following six ASN.1 string types: UTF8String,
* PrintableString, T61String, IA5String, BMPString and
* GeneralString.
* <li> the DER encoding of any other ASN.1 type is not decoded but
* returned as a binary string of colon-separated pairs of
* hexadecimal digits.
* </ul>
* Multi-valued attributes are represented as a comma-separated
* list of values, enclosed in square brackets. See
* {@link Arrays#toString(java.lang.Object[])}.
*
* @return the attribute value's string encoding
*/
@Override
public String getValue() {
return value;
}
/**
* Returns the attribute's ASN.1 DER encoding.
*
* @return a clone of the attribute's DER encoding
*/
public byte[] getEncoded() {
return encoded.clone();
}
/**
* Compares this {@code PKCS12Attribute} and a specified object for
* equality.
*
* @param obj the comparison object
*
* @return true if {@code obj} is a {@code PKCS12Attribute} and
* their DER encodings are equal.
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof PKCS12Attribute)) {
return false;
}
return Arrays.equals(encoded, ((PKCS12Attribute) obj).getEncoded());
}
/**
* Returns the hashcode for this {@code PKCS12Attribute}.
* The hash code is computed from its DER encoding.
*
* @return the hash code
*/
@Override
public int hashCode() {
if (hashValue == -1) {
Arrays.hashCode(encoded);
}
return hashValue;
}
/**
* Returns a string representation of this {@code PKCS12Attribute}.
*
* @return a name/value pair separated by an 'equals' symbol
*/
@Override
public String toString() {
return (name + "=" + value);
}
private byte[] encode(ObjectIdentifier type, String[] values)
throws IOException {
DerOutputStream attribute = new DerOutputStream();
attribute.putOID(type);
DerOutputStream attrContent = new DerOutputStream();
for (String value : values) {
if (COLON_SEPARATED_HEX_PAIRS.matcher(value).matches()) {
byte[] bytes =
new BigInteger(value.replace(":", ""), 16).toByteArray();
if (bytes[0] == 0) {
bytes = Arrays.copyOfRange(bytes, 1, bytes.length);
}
attrContent.putOctetString(bytes);
} else {
attrContent.putUTF8String(value);
}
}
attribute.write(DerValue.tag_Set, attrContent);
DerOutputStream attributeValue = new DerOutputStream();
attributeValue.write(DerValue.tag_Sequence, attribute);
return attributeValue.toByteArray();
}
private void parse(byte[] encoded) throws IOException {
DerInputStream attributeValue = new DerInputStream(encoded);
DerValue[] attrSeq = attributeValue.getSequence(2);
ObjectIdentifier type = attrSeq[0].getOID();
DerInputStream attrContent =
new DerInputStream(attrSeq[1].toByteArray());
DerValue[] attrValueSet = attrContent.getSet(1);
String[] values = new String[attrValueSet.length];
String printableString;
for (int i = 0; i < attrValueSet.length; i++) {
if (attrValueSet[i].tag == DerValue.tag_OctetString) {
values[i] = Debug.toString(attrValueSet[i].getOctetString());
} else if ((printableString = attrValueSet[i].getAsString())
!= null) {
values[i] = printableString;
} else if (attrValueSet[i].tag == DerValue.tag_ObjectId) {
values[i] = attrValueSet[i].getOID().toString();
} else if (attrValueSet[i].tag == DerValue.tag_GeneralizedTime) {
values[i] = attrValueSet[i].getGeneralizedTime().toString();
} else if (attrValueSet[i].tag == DerValue.tag_UtcTime) {
values[i] = attrValueSet[i].getUTCTime().toString();
} else if (attrValueSet[i].tag == DerValue.tag_Integer) {
values[i] = attrValueSet[i].getBigInteger().toString();
} else if (attrValueSet[i].tag == DerValue.tag_Boolean) {
values[i] = String.valueOf(attrValueSet[i].getBoolean());
} else {
values[i] = Debug.toString(attrValueSet[i].getDataBytes());
}
}
this.name = type.toString();
this.value = values.length == 1 ? values[0] : Arrays.toString(values);
}
}

View file

@ -0,0 +1,232 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
/**
* Abstract class for representing access to a system resource.
* All permissions have a name (whose interpretation depends on the subclass),
* as well as abstract functions for defining the semantics of the
* particular Permission subclass.
*
* <p>Most Permission objects also include an "actions" list that tells the actions
* that are permitted for the object. For example,
* for a {@code java.io.FilePermission} object, the permission name is
* the pathname of a file (or directory), and the actions list
* (such as "read, write") specifies which actions are granted for the
* specified file (or for files in the specified directory).
* The actions list is optional for Permission objects, such as
* {@code java.lang.RuntimePermission},
* that don't need such a list; you either have the named permission (such
* as "system.exit") or you don't.
*
* <p>An important method that must be implemented by each subclass is
* the {@code implies} method to compare Permissions. Basically,
* "permission p1 implies permission p2" means that
* if one is granted permission p1, one is naturally granted permission p2.
* Thus, this is not an equality test, but rather more of a
* subset test.
*
* <P> Permission objects are similar to String objects in that they
* are immutable once they have been created. Subclasses should not
* provide methods that can change the state of a permission
* once it has been created.
*
* @see Permissions
* @see PermissionCollection
*
*
* @author Marianne Mueller
* @author Roland Schemers
* @since 1.2
*/
public abstract class Permission implements Guard, java.io.Serializable {
private static final long serialVersionUID = -5636570222231596674L;
private String name;
/**
* Constructs a permission with the specified name.
*
* @param name name of the Permission object being created.
*
*/
public Permission(String name) {
this.name = name;
}
/**
* Implements the guard interface for a permission. The
* {@code SecurityManager.checkPermission} method is called,
* passing this permission object as the permission to check.
* Returns silently if access is granted. Otherwise, throws
* a SecurityException.
*
* @param object the object being guarded (currently ignored).
*
* @throws SecurityException
* if a security manager exists and its
* {@code checkPermission} method doesn't allow access.
*
* @see Guard
* @see GuardedObject
* @see SecurityManager#checkPermission
*
*/
public void checkGuard(Object object) throws SecurityException {
SecurityManager sm = System.getSecurityManager();
if (sm != null) sm.checkPermission(this);
}
/**
* Checks if the specified permission's actions are "implied by"
* this object's actions.
* <P>
* This must be implemented by subclasses of Permission, as they are the
* only ones that can impose semantics on a Permission object.
*
* <p>The {@code implies} method is used by the AccessController to determine
* whether or not a requested permission is implied by another permission that
* is known to be valid in the current execution context.
*
* @param permission the permission to check against.
*
* @return true if the specified permission is implied by this object,
* false if not.
*/
public abstract boolean implies(Permission permission);
/**
* Checks two Permission objects for equality.
* <P>
* Do not use the {@code equals} method for making access control
* decisions; use the {@code implies} method.
*
* @param obj the object we are testing for equality with this object.
*
* @return true if both Permission objects are equivalent.
*/
public abstract boolean equals(Object obj);
/**
* Returns the hash code value for this Permission object.
* <P>
* The required {@code hashCode} behavior for Permission Objects is
* the following:
* <ul>
* <li>Whenever it is invoked on the same Permission object more than
* once during an execution of a Java application, the
* {@code hashCode} method
* must consistently return the same integer. This integer need not
* remain consistent from one execution of an application to another
* execution of the same application.
* <li>If two Permission objects are equal according to the
* {@code equals}
* method, then calling the {@code hashCode} method on each of the
* two Permission objects must produce the same integer result.
* </ul>
*
* @return a hash code value for this object.
*/
public abstract int hashCode();
/**
* Returns the name of this Permission.
* For example, in the case of a {@code java.io.FilePermission},
* the name will be a pathname.
*
* @return the name of this Permission.
*
*/
public final String getName() {
return name;
}
/**
* Returns the actions as a String. This is abstract
* so subclasses can defer creating a String representation until
* one is needed. Subclasses should always return actions in what they
* consider to be their
* canonical form. For example, two FilePermission objects created via
* the following:
*
* <pre>
* perm1 = new FilePermission(p1,"read,write");
* perm2 = new FilePermission(p2,"write,read");
* </pre>
*
* both return
* "read,write" when the {@code getActions} method is invoked.
*
* @return the actions of this Permission.
*
*/
public abstract String getActions();
/**
* Returns an empty PermissionCollection for a given Permission object, or null if
* one is not defined. Subclasses of class Permission should
* override this if they need to store their permissions in a particular
* PermissionCollection object in order to provide the correct semantics
* when the {@code PermissionCollection.implies} method is called.
* If null is returned,
* then the caller of this method is free to store permissions of this
* type in any PermissionCollection they choose (one that uses a Hashtable,
* one that uses a Vector, etc).
*
* @return a new PermissionCollection object for this type of Permission, or
* null if one is not defined.
*/
public PermissionCollection newPermissionCollection() {
return null;
}
/**
* Returns a string describing this Permission. The convention is to
* specify the class name, the permission name, and the actions in
* the following format: '("ClassName" "name" "actions")', or
* '("ClassName" "name")' if actions list is null or empty.
*
* @return information about this Permission.
*/
public String toString() {
String actions = getActions();
if ((actions == null) || (actions.length() == 0)) { // OPTIONAL
return "(\"" + getClass().getName() + "\" \"" + name + "\")";
} else {
return "(\"" + getClass().getName() + "\" \"" + name +
"\" \"" + actions + "\")";
}
}
}

View file

@ -0,0 +1,223 @@
/*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
import java.util.*;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
/**
* Abstract class representing a collection of Permission objects.
*
* <p>With a PermissionCollection, you can:
* <UL>
* <LI> add a permission to the collection using the {@code add} method.
* <LI> check to see if a particular permission is implied in the
* collection, using the {@code implies} method.
* <LI> enumerate all the permissions, using the {@code elements} method.
* </UL>
*
* <p>When it is desirable to group together a number of Permission objects
* of the same type, the {@code newPermissionCollection} method on that
* particular type of Permission object should first be called. The default
* behavior (from the Permission class) is to simply return null.
* Subclasses of class Permission override the method if they need to store
* their permissions in a particular PermissionCollection object in order
* to provide the correct semantics when the
* {@code PermissionCollection.implies} method is called.
* If a non-null value is returned, that PermissionCollection must be used.
* If null is returned, then the caller of {@code newPermissionCollection}
* is free to store permissions of the
* given type in any PermissionCollection they choose
* (one that uses a Hashtable, one that uses a Vector, etc).
*
* <p>The PermissionCollection returned by the
* {@code Permission.newPermissionCollection}
* method is a homogeneous collection, which stores only Permission objects
* for a given Permission type. A PermissionCollection may also be
* heterogeneous. For example, Permissions is a PermissionCollection
* subclass that represents a collection of PermissionCollections.
* That is, its members are each a homogeneous PermissionCollection.
* For example, a Permissions object might have a FilePermissionCollection
* for all the FilePermission objects, a SocketPermissionCollection for all the
* SocketPermission objects, and so on. Its {@code add} method adds a
* permission to the appropriate collection.
*
* <p>Whenever a permission is added to a heterogeneous PermissionCollection
* such as Permissions, and the PermissionCollection doesn't yet contain a
* PermissionCollection of the specified permission's type, the
* PermissionCollection should call
* the {@code newPermissionCollection} method on the permission's class
* to see if it requires a special PermissionCollection. If
* {@code newPermissionCollection}
* returns null, the PermissionCollection
* is free to store the permission in any type of PermissionCollection it
* desires (one using a Hashtable, one using a Vector, etc.). For example,
* the Permissions object uses a default PermissionCollection implementation
* that stores the permission objects in a Hashtable.
*
* <p> Subclass implementations of PermissionCollection should assume
* that they may be called simultaneously from multiple threads,
* and therefore should be synchronized properly. Furthermore,
* Enumerations returned via the {@code elements} method are
* not <em>fail-fast</em>. Modifications to a collection should not be
* performed while enumerating over that collection.
*
* @see Permission
* @see Permissions
*
*
* @author Roland Schemers
* @since 1.2
*/
public abstract class PermissionCollection implements java.io.Serializable {
private static final long serialVersionUID = -6727011328946861783L;
// when set, add will throw an exception.
private volatile boolean readOnly;
/**
* Adds a permission object to the current collection of permission objects.
*
* @param permission the Permission object to add.
*
* @exception SecurityException - if this PermissionCollection object
* has been marked readonly
* @exception IllegalArgumentException - if this PermissionCollection
* object is a homogeneous collection and the permission
* is not of the correct type.
*/
public abstract void add(Permission permission);
/**
* Checks to see if the specified permission is implied by
* the collection of Permission objects held in this PermissionCollection.
*
* @param permission the Permission object to compare.
*
* @return true if "permission" is implied by the permissions in
* the collection, false if not.
*/
public abstract boolean implies(Permission permission);
/**
* Returns an enumeration of all the Permission objects in the collection.
*
* @return an enumeration of all the Permissions.
* @see #elementsAsStream()
*/
public abstract Enumeration<Permission> elements();
/**
* Returns a stream of all the Permission objects in the collection.
*
* <p> The collection should not be modified (see {@link #add}) during the
* execution of the terminal stream operation. Otherwise, the result of the
* terminal stream operation is undefined.
*
* @implSpec
* The default implementation creates a stream whose source is derived from
* the enumeration returned from a call to {@link #elements()}.
*
* @return a stream of all the Permissions.
* @since 9
*/
public Stream<Permission> elementsAsStream() {
int characteristics = isReadOnly()
? Spliterator.NONNULL | Spliterator.IMMUTABLE
: Spliterator.NONNULL;
return StreamSupport.stream(
Spliterators.spliteratorUnknownSize(
elements().asIterator(), characteristics),
false);
}
/**
* Marks this PermissionCollection object as "readonly". After
* a PermissionCollection object
* is marked as readonly, no new Permission objects can be added to it
* using {@code add}.
*/
public void setReadOnly() {
readOnly = true;
}
/**
* Returns true if this PermissionCollection object is marked as readonly.
* If it is readonly, no new Permission objects can be added to it
* using {@code add}.
*
* <p>By default, the object is <i>not</i> readonly. It can be set to
* readonly by a call to {@code setReadOnly}.
*
* @return true if this PermissionCollection object is marked as readonly,
* false otherwise.
*/
public boolean isReadOnly() {
return readOnly;
}
/**
* Returns a string describing this PermissionCollection object,
* providing information about all the permissions it contains.
* The format is:
* <pre>
* super.toString() (
* // enumerate all the Permission
* // objects and call toString() on them,
* // one per line..
* )</pre>
*
* {@code super.toString} is a call to the {@code toString}
* method of this
* object's superclass, which is Object. The result is
* this PermissionCollection's type name followed by this object's
* hashcode, thus enabling clients to differentiate different
* PermissionCollections object, even if they contain the same permissions.
*
* @return information about this PermissionCollection object,
* as described above.
*
*/
public String toString() {
Enumeration<Permission> enum_ = elements();
StringBuilder sb = new StringBuilder();
sb.append(super.toString()+" (\n");
while (enum_.hasMoreElements()) {
try {
sb.append(" ");
sb.append(enum_.nextElement().toString());
sb.append("\n");
} catch (NoSuchElementException e){
// ignore
}
}
sb.append(")\n");
return sb.toString();
}
}

View file

@ -0,0 +1,588 @@
/*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.NoSuchElementException;
import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.Iterator;
import java.util.Collections;
import java.util.concurrent.ConcurrentHashMap;
import java.io.Serializable;
import java.io.ObjectStreamField;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.IOException;
/**
* This class represents a heterogeneous collection of Permissions. That is,
* it contains different types of Permission objects, organized into
* PermissionCollections. For example, if any
* {@code java.io.FilePermission} objects are added to an instance of
* this class, they are all stored in a single
* PermissionCollection. It is the PermissionCollection returned by a call to
* the {@code newPermissionCollection} method in the FilePermission class.
* Similarly, any {@code java.lang.RuntimePermission} objects are
* stored in the PermissionCollection returned by a call to the
* {@code newPermissionCollection} method in the
* RuntimePermission class. Thus, this class represents a collection of
* PermissionCollections.
*
* <p>When the {@code add} method is called to add a Permission, the
* Permission is stored in the appropriate PermissionCollection. If no such
* collection exists yet, the Permission object's class is determined and the
* {@code newPermissionCollection} method is called on that class to create
* the PermissionCollection and add it to the Permissions object. If
* {@code newPermissionCollection} returns null, then a default
* PermissionCollection that uses a hashtable will be created and used. Each
* hashtable entry stores a Permission object as both the key and the value.
*
* <p> Enumerations returned via the {@code elements} method are
* not <em>fail-fast</em>. Modifications to a collection should not be
* performed while enumerating over that collection.
*
* @see Permission
* @see PermissionCollection
* @see AllPermission
*
*
* @author Marianne Mueller
* @author Roland Schemers
* @since 1.2
*
* @serial exclude
*/
public final class Permissions extends PermissionCollection
implements Serializable
{
/**
* Key is permissions Class, value is PermissionCollection for that class.
* Not serialized; see serialization section at end of class.
*/
private transient ConcurrentHashMap<Class<?>, PermissionCollection> permsMap;
// optimization. keep track of whether unresolved permissions need to be
// checked
private transient boolean hasUnresolved = false;
// optimization. keep track of the AllPermission collection
// - package private for ProtectionDomain optimization
PermissionCollection allPermission;
/**
* Creates a new Permissions object containing no PermissionCollections.
*/
public Permissions() {
permsMap = new ConcurrentHashMap<>(11);
allPermission = null;
}
/**
* Adds a permission object to the PermissionCollection for the class the
* permission belongs to. For example, if <i>permission</i> is a
* FilePermission, it is added to the FilePermissionCollection stored
* in this Permissions object.
*
* This method creates
* a new PermissionCollection object (and adds the permission to it)
* if an appropriate collection does not yet exist.
*
* @param permission the Permission object to add.
*
* @exception SecurityException if this Permissions object is
* marked as readonly.
*
* @see PermissionCollection#isReadOnly()
*/
@Override
public void add(Permission permission) {
if (isReadOnly())
throw new SecurityException(
"attempt to add a Permission to a readonly Permissions object");
PermissionCollection pc = getPermissionCollection(permission, true);
pc.add(permission);
// No sync; staleness -> optimizations delayed, which is OK
if (permission instanceof AllPermission) {
allPermission = pc;
}
if (permission instanceof UnresolvedPermission) {
hasUnresolved = true;
}
}
/**
* Checks to see if this object's PermissionCollection for permissions of
* the specified permission's class implies the permissions
* expressed in the <i>permission</i> object. Returns true if the
* combination of permissions in the appropriate PermissionCollection
* (e.g., a FilePermissionCollection for a FilePermission) together
* imply the specified permission.
*
* <p>For example, suppose there is a FilePermissionCollection in this
* Permissions object, and it contains one FilePermission that specifies
* "read" access for all files in all subdirectories of the "/tmp"
* directory, and another FilePermission that specifies "write" access
* for all files in the "/tmp/scratch/foo" directory.
* Then if the {@code implies} method
* is called with a permission specifying both "read" and "write" access
* to files in the "/tmp/scratch/foo" directory, {@code true} is
* returned.
*
* <p>Additionally, if this PermissionCollection contains the
* AllPermission, this method will always return true.
*
* @param permission the Permission object to check.
*
* @return true if "permission" is implied by the permissions in the
* PermissionCollection it
* belongs to, false if not.
*/
@Override
public boolean implies(Permission permission) {
// No sync; staleness -> skip optimization, which is OK
if (allPermission != null) {
return true; // AllPermission has already been added
} else {
PermissionCollection pc = getPermissionCollection(permission,
false);
if (pc != null) {
return pc.implies(permission);
} else {
// none found
return false;
}
}
}
/**
* Returns an enumeration of all the Permission objects in all the
* PermissionCollections in this Permissions object.
*
* @return an enumeration of all the Permissions.
*/
@Override
public Enumeration<Permission> elements() {
// go through each Permissions in the hash table
// and call their elements() function.
return new PermissionsEnumerator(permsMap.values().iterator());
}
/**
* Gets the PermissionCollection in this Permissions object for
* permissions whose type is the same as that of <i>p</i>.
* For example, if <i>p</i> is a FilePermission,
* the FilePermissionCollection
* stored in this Permissions object will be returned.
*
* If createEmpty is true,
* this method creates a new PermissionCollection object for the specified
* type of permission objects if one does not yet exist.
* To do so, it first calls the {@code newPermissionCollection} method
* on <i>p</i>. Subclasses of class Permission
* override that method if they need to store their permissions in a
* particular PermissionCollection object in order to provide the
* correct semantics when the {@code PermissionCollection.implies}
* method is called.
* If the call returns a PermissionCollection, that collection is stored
* in this Permissions object. If the call returns null and createEmpty
* is true, then
* this method instantiates and stores a default PermissionCollection
* that uses a hashtable to store its permission objects.
*
* createEmpty is ignored when creating empty PermissionCollection
* for unresolved permissions because of the overhead of determining the
* PermissionCollection to use.
*
* createEmpty should be set to false when this method is invoked from
* implies() because it incurs the additional overhead of creating and
* adding an empty PermissionCollection that will just return false.
* It should be set to true when invoked from add().
*/
private PermissionCollection getPermissionCollection(Permission p,
boolean createEmpty) {
Class<?> c = p.getClass();
if (!hasUnresolved && !createEmpty) {
return permsMap.get(c);
}
// Create and add permission collection to map if it is absent.
// NOTE: cannot use lambda for mappingFunction parameter until
// JDK-8076596 is fixed.
return permsMap.computeIfAbsent(c,
new java.util.function.Function<>() {
@Override
public PermissionCollection apply(Class<?> k) {
// Check for unresolved permissions
PermissionCollection pc =
(hasUnresolved ? getUnresolvedPermissions(p) : null);
// if still null, create a new collection
if (pc == null && createEmpty) {
pc = p.newPermissionCollection();
// still no PermissionCollection?
// We'll give them a PermissionsHash.
if (pc == null) {
pc = new PermissionsHash();
}
}
return pc;
}
}
);
}
/**
* Resolves any unresolved permissions of type p.
*
* @param p the type of unresolved permission to resolve
*
* @return PermissionCollection containing the unresolved permissions,
* or null if there were no unresolved permissions of type p.
*
*/
private PermissionCollection getUnresolvedPermissions(Permission p)
{
UnresolvedPermissionCollection uc =
(UnresolvedPermissionCollection) permsMap.get(UnresolvedPermission.class);
// we have no unresolved permissions if uc is null
if (uc == null)
return null;
List<UnresolvedPermission> unresolvedPerms =
uc.getUnresolvedPermissions(p);
// we have no unresolved permissions of this type if unresolvedPerms is null
if (unresolvedPerms == null)
return null;
java.security.cert.Certificate[] certs = null;
Object[] signers = p.getClass().getSigners();
int n = 0;
if (signers != null) {
for (int j=0; j < signers.length; j++) {
if (signers[j] instanceof java.security.cert.Certificate) {
n++;
}
}
certs = new java.security.cert.Certificate[n];
n = 0;
for (int j=0; j < signers.length; j++) {
if (signers[j] instanceof java.security.cert.Certificate) {
certs[n++] = (java.security.cert.Certificate)signers[j];
}
}
}
PermissionCollection pc = null;
synchronized (unresolvedPerms) {
int len = unresolvedPerms.size();
for (int i = 0; i < len; i++) {
UnresolvedPermission up = unresolvedPerms.get(i);
Permission perm = up.resolve(p, certs);
if (perm != null) {
if (pc == null) {
pc = p.newPermissionCollection();
if (pc == null)
pc = new PermissionsHash();
}
pc.add(perm);
}
}
}
return pc;
}
private static final long serialVersionUID = 4858622370623524688L;
// Need to maintain serialization interoperability with earlier releases,
// which had the serializable field:
// private Hashtable perms;
/**
* @serialField perms java.util.Hashtable
* A table of the Permission classes and PermissionCollections.
* @serialField allPermission java.security.PermissionCollection
*/
private static final ObjectStreamField[] serialPersistentFields = {
new ObjectStreamField("perms", Hashtable.class),
new ObjectStreamField("allPermission", PermissionCollection.class),
};
/**
* @serialData Default fields.
*/
/*
* Writes the contents of the permsMap field out as a Hashtable for
* serialization compatibility with earlier releases. allPermission
* unchanged.
*/
private void writeObject(ObjectOutputStream out) throws IOException {
// Don't call out.defaultWriteObject()
// Copy perms into a Hashtable
Hashtable<Class<?>, PermissionCollection> perms =
new Hashtable<>(permsMap.size()*2); // no sync; estimate
perms.putAll(permsMap);
// Write out serializable fields
ObjectOutputStream.PutField pfields = out.putFields();
pfields.put("allPermission", allPermission); // no sync; staleness OK
pfields.put("perms", perms);
out.writeFields();
}
/*
* Reads in a Hashtable of Class/PermissionCollections and saves them in the
* permsMap field. Reads in allPermission.
*/
private void readObject(ObjectInputStream in) throws IOException,
ClassNotFoundException {
// Don't call defaultReadObject()
// Read in serialized fields
ObjectInputStream.GetField gfields = in.readFields();
// Get allPermission
allPermission = (PermissionCollection) gfields.get("allPermission", null);
// Get permissions
// writeObject writes a Hashtable<Class<?>, PermissionCollection> for
// the perms key, so this cast is safe, unless the data is corrupt.
@SuppressWarnings("unchecked")
Hashtable<Class<?>, PermissionCollection> perms =
(Hashtable<Class<?>, PermissionCollection>)gfields.get("perms", null);
permsMap = new ConcurrentHashMap<>(perms.size()*2);
permsMap.putAll(perms);
// Set hasUnresolved
UnresolvedPermissionCollection uc =
(UnresolvedPermissionCollection) permsMap.get(UnresolvedPermission.class);
hasUnresolved = (uc != null && uc.elements().hasMoreElements());
}
}
final class PermissionsEnumerator implements Enumeration<Permission> {
// all the perms
private Iterator<PermissionCollection> perms;
// the current set
private Enumeration<Permission> permset;
PermissionsEnumerator(Iterator<PermissionCollection> e) {
perms = e;
permset = getNextEnumWithMore();
}
// No need to synchronize; caller should sync on object as required
public boolean hasMoreElements() {
// if we enter with permissionimpl null, we know
// there are no more left.
if (permset == null)
return false;
// try to see if there are any left in the current one
if (permset.hasMoreElements())
return true;
// get the next one that has something in it...
permset = getNextEnumWithMore();
// if it is null, we are done!
return (permset != null);
}
// No need to synchronize; caller should sync on object as required
public Permission nextElement() {
// hasMoreElements will update permset to the next permset
// with something in it...
if (hasMoreElements()) {
return permset.nextElement();
} else {
throw new NoSuchElementException("PermissionsEnumerator");
}
}
private Enumeration<Permission> getNextEnumWithMore() {
while (perms.hasNext()) {
PermissionCollection pc = perms.next();
Enumeration<Permission> next =pc.elements();
if (next.hasMoreElements())
return next;
}
return null;
}
}
/**
* A PermissionsHash stores a homogeneous set of permissions in a hashtable.
*
* @see Permission
* @see Permissions
*
*
* @author Roland Schemers
*
* @serial include
*/
final class PermissionsHash extends PermissionCollection
implements Serializable
{
/**
* Key and value are (same) permissions objects.
* Not serialized; see serialization section at end of class.
*/
private transient ConcurrentHashMap<Permission, Permission> permsMap;
/**
* Create an empty PermissionsHash object.
*/
PermissionsHash() {
permsMap = new ConcurrentHashMap<>(11);
}
/**
* Adds a permission to the PermissionsHash.
*
* @param permission the Permission object to add.
*/
@Override
public void add(Permission permission) {
permsMap.put(permission, permission);
}
/**
* Check and see if this set of permissions implies the permissions
* expressed in "permission".
*
* @param permission the Permission object to compare
*
* @return true if "permission" is a proper subset of a permission in
* the set, false if not.
*/
@Override
public boolean implies(Permission permission) {
// attempt a fast lookup and implies. If that fails
// then enumerate through all the permissions.
Permission p = permsMap.get(permission);
// If permission is found, then p.equals(permission)
if (p == null) {
for (Permission p_ : permsMap.values()) {
if (p_.implies(permission))
return true;
}
return false;
} else {
return true;
}
}
/**
* Returns an enumeration of all the Permission objects in the container.
*
* @return an enumeration of all the Permissions.
*/
@Override
public Enumeration<Permission> elements() {
return permsMap.elements();
}
private static final long serialVersionUID = -8491988220802933440L;
// Need to maintain serialization interoperability with earlier releases,
// which had the serializable field:
// private Hashtable perms;
/**
* @serialField perms java.util.Hashtable
* A table of the Permissions (both key and value are same).
*/
private static final ObjectStreamField[] serialPersistentFields = {
new ObjectStreamField("perms", Hashtable.class),
};
/**
* @serialData Default fields.
*/
/*
* Writes the contents of the permsMap field out as a Hashtable for
* serialization compatibility with earlier releases.
*/
private void writeObject(ObjectOutputStream out) throws IOException {
// Don't call out.defaultWriteObject()
// Copy perms into a Hashtable
Hashtable<Permission, Permission> perms =
new Hashtable<>(permsMap.size()*2);
perms.putAll(permsMap);
// Write out serializable fields
ObjectOutputStream.PutField pfields = out.putFields();
pfields.put("perms", perms);
out.writeFields();
}
/*
* Reads in a Hashtable of Permission/Permission and saves them in the
* permsMap field.
*/
private void readObject(ObjectInputStream in) throws IOException,
ClassNotFoundException {
// Don't call defaultReadObject()
// Read in serialized fields
ObjectInputStream.GetField gfields = in.readFields();
// Get permissions
// writeObject writes a Hashtable<Class<?>, PermissionCollection> for
// the perms key, so this cast is safe, unless the data is corrupt.
@SuppressWarnings("unchecked")
Hashtable<Permission, Permission> perms =
(Hashtable<Permission, Permission>)gfields.get("perms", null);
permsMap = new ConcurrentHashMap<>(perms.size()*2);
permsMap.putAll(perms);
}
}

View file

@ -0,0 +1,869 @@
/*
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
import java.util.Enumeration;
import java.util.WeakHashMap;
import java.util.Objects;
import sun.security.jca.GetInstance;
import sun.security.util.Debug;
import sun.security.util.SecurityConstants;
/**
* A Policy object is responsible for determining whether code executing
* in the Java runtime environment has permission to perform a
* security-sensitive operation.
*
* <p> There is only one Policy object installed in the runtime at any
* given time. A Policy object can be installed by calling the
* {@code setPolicy} method. The installed Policy object can be
* obtained by calling the {@code getPolicy} method.
*
* <p> If no Policy object has been installed in the runtime, a call to
* {@code getPolicy} installs an instance of the default Policy
* implementation (a default subclass implementation of this abstract class).
* The default Policy implementation can be changed by setting the value
* of the {@code policy.provider} security property to the fully qualified
* name of the desired Policy subclass implementation. The system class loader
* is used to load this class.
*
* <p> Application code can directly subclass Policy to provide a custom
* implementation. In addition, an instance of a Policy object can be
* constructed by invoking one of the {@code getInstance} factory methods
* with a standard type. The default policy type is "JavaPolicy".
*
* <p> Once a Policy instance has been installed (either by default, or by
* calling {@code setPolicy}), the Java runtime invokes its
* {@code implies} method when it needs to
* determine whether executing code (encapsulated in a ProtectionDomain)
* can perform SecurityManager-protected operations. How a Policy object
* retrieves its policy data is up to the Policy implementation itself.
* The policy data may be stored, for example, in a flat ASCII file,
* in a serialized binary file of the Policy class, or in a database.
*
* <p> The {@code refresh} method causes the policy object to
* refresh/reload its data. This operation is implementation-dependent.
* For example, if the policy object stores its data in configuration files,
* calling {@code refresh} will cause it to re-read the configuration
* policy files. If a refresh operation is not supported, this method does
* nothing. Note that refreshed policy may not have an effect on classes
* in a particular ProtectionDomain. This is dependent on the Policy
* provider's implementation of the {@code implies}
* method and its PermissionCollection caching strategy.
*
* @author Roland Schemers
* @author Gary Ellison
* @since 1.2
* @see java.security.Provider
* @see java.security.ProtectionDomain
* @see java.security.Permission
* @see java.security.Security security properties
*/
public abstract class Policy {
/**
* A read-only empty PermissionCollection instance.
* @since 1.6
*/
public static final PermissionCollection UNSUPPORTED_EMPTY_COLLECTION =
new UnsupportedEmptyCollection();
// Information about the system-wide policy.
private static class PolicyInfo {
// the system-wide policy
final Policy policy;
// a flag indicating if the system-wide policy has been initialized
final boolean initialized;
PolicyInfo(Policy policy, boolean initialized) {
this.policy = policy;
this.initialized = initialized;
}
}
// PolicyInfo is volatile since we apply DCL during initialization.
// For correctness, care must be taken to read the field only once and only
// write to it after any other initialization action has taken place.
private static volatile PolicyInfo policyInfo = new PolicyInfo(null, false);
private static final Debug debug = Debug.getInstance("policy");
// Default policy provider
private static final String DEFAULT_POLICY =
"sun.security.provider.PolicyFile";
// Cache mapping ProtectionDomain.Key to PermissionCollection
private WeakHashMap<ProtectionDomain.Key, PermissionCollection> pdMapping;
/** package private for AccessControlContext and ProtectionDomain */
static boolean isSet() {
PolicyInfo pi = policyInfo;
return pi.policy != null && pi.initialized == true;
}
private static void checkPermission(String type) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new SecurityPermission("createPolicy." + type));
}
}
/**
* Returns the installed Policy object. This value should not be cached,
* as it may be changed by a call to {@code setPolicy}.
* This method first calls
* {@code SecurityManager.checkPermission} with a
* {@code SecurityPermission("getPolicy")} permission
* to ensure it's ok to get the Policy object.
*
* @return the installed Policy.
*
* @throws SecurityException
* if a security manager exists and its
* {@code checkPermission} method doesn't allow
* getting the Policy object.
*
* @see SecurityManager#checkPermission(Permission)
* @see #setPolicy(java.security.Policy)
*/
public static Policy getPolicy()
{
SecurityManager sm = System.getSecurityManager();
if (sm != null)
sm.checkPermission(SecurityConstants.GET_POLICY_PERMISSION);
return getPolicyNoCheck();
}
/**
* Returns the installed Policy object, skipping the security check.
* Used by ProtectionDomain and getPolicy.
*
* @return the installed Policy.
*/
static Policy getPolicyNoCheck()
{
PolicyInfo pi = policyInfo;
// Use double-check idiom to avoid locking if system-wide policy is
// already initialized
if (pi.initialized == false || pi.policy == null) {
synchronized (Policy.class) {
pi = policyInfo;
if (pi.policy == null) {
return loadPolicyProvider();
}
}
}
return pi.policy;
}
/**
* Loads and instantiates a Policy implementation specified by the
* policy.provider security property. Note that this method should only
* be called by getPolicyNoCheck and from within a synchronized block with
* an intrinsic lock on the Policy.class.
*/
private static Policy loadPolicyProvider() {
String policyProvider =
AccessController.doPrivileged(new PrivilegedAction<>() {
@Override
public String run() {
return Security.getProperty("policy.provider");
}
});
/*
* If policy.provider is not set or is set to the default provider,
* simply instantiate it and return.
*/
if (policyProvider == null || policyProvider.isEmpty() ||
policyProvider.equals(DEFAULT_POLICY))
{
Policy polFile = new sun.security.provider.PolicyFile();
policyInfo = new PolicyInfo(polFile, true);
return polFile;
}
/*
* Locate, load, and instantiate the policy.provider impl using
* the system class loader. While doing so, install the bootstrap
* provider to avoid potential recursion.
*/
Policy polFile = new sun.security.provider.PolicyFile();
policyInfo = new PolicyInfo(polFile, false);
Policy pol = AccessController.doPrivileged(new PrivilegedAction<>() {
@Override
public Policy run() {
try {
ClassLoader scl = ClassLoader.getSystemClassLoader();
@SuppressWarnings("deprecation")
Object o = Class.forName(policyProvider, true, scl).newInstance();
return (Policy)o;
} catch (Exception e) {
if (debug != null) {
debug.println("policy provider " + policyProvider +
" not available");
e.printStackTrace();
}
return null;
}
}
});
if (pol == null) {
// Fallback and use the system default implementation
if (debug != null) {
debug.println("using " + DEFAULT_POLICY);
}
pol = polFile;
}
policyInfo = new PolicyInfo(pol, true);
return pol;
}
/**
* Sets the system-wide Policy object. This method first calls
* {@code SecurityManager.checkPermission} with a
* {@code SecurityPermission("setPolicy")}
* permission to ensure it's ok to set the Policy.
*
* @param p the new system Policy object.
*
* @throws SecurityException
* if a security manager exists and its
* {@code checkPermission} method doesn't allow
* setting the Policy.
*
* @see SecurityManager#checkPermission(Permission)
* @see #getPolicy()
*
*/
public static void setPolicy(Policy p)
{
SecurityManager sm = System.getSecurityManager();
if (sm != null) sm.checkPermission(
new SecurityPermission("setPolicy"));
if (p != null) {
initPolicy(p);
}
synchronized (Policy.class) {
policyInfo = new PolicyInfo(p, p != null);
}
}
/**
* Initialize superclass state such that a legacy provider can
* handle queries for itself.
*
* @since 1.4
*/
private static void initPolicy (final Policy p) {
/*
* A policy provider not on the bootclasspath could trigger
* security checks fulfilling a call to either Policy.implies
* or Policy.getPermissions. If this does occur the provider
* must be able to answer for it's own ProtectionDomain
* without triggering additional security checks, otherwise
* the policy implementation will end up in an infinite
* recursion.
*
* To mitigate this, the provider can collect it's own
* ProtectionDomain and associate a PermissionCollection while
* it is being installed. The currently installed policy
* provider (if there is one) will handle calls to
* Policy.implies or Policy.getPermissions during this
* process.
*
* This Policy superclass caches away the ProtectionDomain and
* statically binds permissions so that legacy Policy
* implementations will continue to function.
*/
ProtectionDomain policyDomain =
AccessController.doPrivileged(new PrivilegedAction<>() {
public ProtectionDomain run() {
return p.getClass().getProtectionDomain();
}
});
/*
* Collect the permissions granted to this protection domain
* so that the provider can be security checked while processing
* calls to Policy.implies or Policy.getPermissions.
*/
PermissionCollection policyPerms = null;
synchronized (p) {
if (p.pdMapping == null) {
p.pdMapping = new WeakHashMap<>();
}
}
if (policyDomain.getCodeSource() != null) {
Policy pol = policyInfo.policy;
if (pol != null) {
policyPerms = pol.getPermissions(policyDomain);
}
if (policyPerms == null) { // assume it has all
policyPerms = new Permissions();
policyPerms.add(SecurityConstants.ALL_PERMISSION);
}
synchronized (p.pdMapping) {
// cache of pd to permissions
p.pdMapping.put(policyDomain.key, policyPerms);
}
}
return;
}
/**
* Returns a Policy object of the specified type.
*
* <p> This method traverses the list of registered security providers,
* starting with the most preferred Provider.
* A new Policy object encapsulating the
* PolicySpi implementation from the first
* Provider that supports the specified type is returned.
*
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @implNote
* The JDK Reference Implementation additionally uses the
* {@code jdk.security.provider.preferred}
* {@link Security#getProperty(String) Security} property to determine
* the preferred provider order for the specified algorithm. This
* may be different than the order of providers returned by
* {@link Security#getProviders() Security.getProviders()}.
*
* @param type the specified Policy type. See the Policy section in the
* <a href=
* "{@docRoot}/../specs/security/standard-names.html#policy-types">
* Java Security Standard Algorithm Names Specification</a>
* for a list of standard Policy types.
*
* @param params parameters for the Policy, which may be null.
*
* @return the new {@code Policy} object
*
* @throws IllegalArgumentException if the specified parameters
* are not understood by the {@code PolicySpi} implementation
* from the selected {@code Provider}
*
* @throws NoSuchAlgorithmException if no {@code Provider} supports
* a {@code PolicySpi} implementation for the specified type
*
* @throws NullPointerException if {@code type} is {@code null}
*
* @throws SecurityException if the caller does not have permission
* to get a {@code Policy} instance for the specified type.
*
* @see Provider
* @since 1.6
*/
public static Policy getInstance(String type, Policy.Parameters params)
throws NoSuchAlgorithmException {
Objects.requireNonNull(type, "null type name");
checkPermission(type);
try {
GetInstance.Instance instance = GetInstance.getInstance("Policy",
PolicySpi.class,
type,
params);
return new PolicyDelegate((PolicySpi)instance.impl,
instance.provider,
type,
params);
} catch (NoSuchAlgorithmException nsae) {
return handleException(nsae);
}
}
/**
* Returns a Policy object of the specified type.
*
* <p> A new Policy object encapsulating the
* PolicySpi implementation from the specified provider
* is returned. The specified provider must be registered
* in the provider list.
*
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param type the specified Policy type. See the Policy section in the
* <a href=
* "{@docRoot}/../specs/security/standard-names.html#policy-types">
* Java Security Standard Algorithm Names Specification</a>
* for a list of standard Policy types.
*
* @param params parameters for the Policy, which may be null.
*
* @param provider the provider.
*
* @return the new {@code Policy} object
*
* @throws IllegalArgumentException if the specified provider
* is {@code null} or empty, or if the specified parameters are
* not understood by the {@code PolicySpi} implementation from
* the specified provider
*
* @throws NoSuchAlgorithmException if the specified provider does not
* support a {@code PolicySpi} implementation for the specified
* type
*
* @throws NoSuchProviderException if the specified provider is not
* registered in the security provider list
*
* @throws NullPointerException if {@code type} is {@code null}
*
* @throws SecurityException if the caller does not have permission
* to get a {@code Policy} instance for the specified type
*
* @see Provider
* @since 1.6
*/
public static Policy getInstance(String type,
Policy.Parameters params,
String provider)
throws NoSuchProviderException, NoSuchAlgorithmException {
Objects.requireNonNull(type, "null type name");
if (provider == null || provider.length() == 0) {
throw new IllegalArgumentException("missing provider");
}
checkPermission(type);
try {
GetInstance.Instance instance = GetInstance.getInstance("Policy",
PolicySpi.class,
type,
params,
provider);
return new PolicyDelegate((PolicySpi)instance.impl,
instance.provider,
type,
params);
} catch (NoSuchAlgorithmException nsae) {
return handleException(nsae);
}
}
/**
* Returns a Policy object of the specified type.
*
* <p> A new Policy object encapsulating the
* PolicySpi implementation from the specified Provider
* object is returned. Note that the specified Provider object
* does not have to be registered in the provider list.
*
* @param type the specified Policy type. See the Policy section in the
* <a href=
* "{@docRoot}/../specs/security/standard-names.html#policy-types">
* Java Security Standard Algorithm Names Specification</a>
* for a list of standard Policy types.
*
* @param params parameters for the Policy, which may be null.
*
* @param provider the Provider.
*
* @return the new {@code Policy} object
*
* @throws IllegalArgumentException if the specified {@code Provider}
* is {@code null}, or if the specified parameters are not
* understood by the {@code PolicySpi} implementation from the
* specified {@code Provider}
*
* @throws NoSuchAlgorithmException if the specified {@code Provider}
* does not support a {@code PolicySpi} implementation for
* the specified type
*
* @throws NullPointerException if {@code type} is {@code null}
*
* @throws SecurityException if the caller does not have permission
* to get a {@code Policy} instance for the specified type
*
* @see Provider
* @since 1.6
*/
public static Policy getInstance(String type,
Policy.Parameters params,
Provider provider)
throws NoSuchAlgorithmException {
Objects.requireNonNull(type, "null type name");
if (provider == null) {
throw new IllegalArgumentException("missing provider");
}
checkPermission(type);
try {
GetInstance.Instance instance = GetInstance.getInstance("Policy",
PolicySpi.class,
type,
params,
provider);
return new PolicyDelegate((PolicySpi)instance.impl,
instance.provider,
type,
params);
} catch (NoSuchAlgorithmException nsae) {
return handleException(nsae);
}
}
private static Policy handleException(NoSuchAlgorithmException nsae)
throws NoSuchAlgorithmException {
Throwable cause = nsae.getCause();
if (cause instanceof IllegalArgumentException) {
throw (IllegalArgumentException)cause;
}
throw nsae;
}
/**
* Return the Provider of this Policy.
*
* <p> This Policy instance will only have a Provider if it
* was obtained via a call to {@code Policy.getInstance}.
* Otherwise this method returns null.
*
* @return the Provider of this Policy, or null.
*
* @since 1.6
*/
public Provider getProvider() {
return null;
}
/**
* Return the type of this Policy.
*
* <p> This Policy instance will only have a type if it
* was obtained via a call to {@code Policy.getInstance}.
* Otherwise this method returns null.
*
* @return the type of this Policy, or null.
*
* @since 1.6
*/
public String getType() {
return null;
}
/**
* Return Policy parameters.
*
* <p> This Policy instance will only have parameters if it
* was obtained via a call to {@code Policy.getInstance}.
* Otherwise this method returns null.
*
* @return Policy parameters, or null.
*
* @since 1.6
*/
public Policy.Parameters getParameters() {
return null;
}
/**
* Return a PermissionCollection object containing the set of
* permissions granted to the specified CodeSource.
*
* <p> Applications are discouraged from calling this method
* since this operation may not be supported by all policy implementations.
* Applications should solely rely on the {@code implies} method
* to perform policy checks. If an application absolutely must call
* a getPermissions method, it should call
* {@code getPermissions(ProtectionDomain)}.
*
* <p> The default implementation of this method returns
* Policy.UNSUPPORTED_EMPTY_COLLECTION. This method can be
* overridden if the policy implementation can return a set of
* permissions granted to a CodeSource.
*
* @param codesource the CodeSource to which the returned
* PermissionCollection has been granted.
*
* @return a set of permissions granted to the specified CodeSource.
* If this operation is supported, the returned
* set of permissions must be a new mutable instance
* and it must support heterogeneous Permission types.
* If this operation is not supported,
* Policy.UNSUPPORTED_EMPTY_COLLECTION is returned.
*/
public PermissionCollection getPermissions(CodeSource codesource) {
return Policy.UNSUPPORTED_EMPTY_COLLECTION;
}
/**
* Return a PermissionCollection object containing the set of
* permissions granted to the specified ProtectionDomain.
*
* <p> Applications are discouraged from calling this method
* since this operation may not be supported by all policy implementations.
* Applications should rely on the {@code implies} method
* to perform policy checks.
*
* <p> The default implementation of this method first retrieves
* the permissions returned via {@code getPermissions(CodeSource)}
* (the CodeSource is taken from the specified ProtectionDomain),
* as well as the permissions located inside the specified ProtectionDomain.
* All of these permissions are then combined and returned in a new
* PermissionCollection object. If {@code getPermissions(CodeSource)}
* returns Policy.UNSUPPORTED_EMPTY_COLLECTION, then this method
* returns the permissions contained inside the specified ProtectionDomain
* in a new PermissionCollection object.
*
* <p> This method can be overridden if the policy implementation
* supports returning a set of permissions granted to a ProtectionDomain.
*
* @param domain the ProtectionDomain to which the returned
* PermissionCollection has been granted.
*
* @return a set of permissions granted to the specified ProtectionDomain.
* If this operation is supported, the returned
* set of permissions must be a new mutable instance
* and it must support heterogeneous Permission types.
* If this operation is not supported,
* Policy.UNSUPPORTED_EMPTY_COLLECTION is returned.
*
* @since 1.4
*/
public PermissionCollection getPermissions(ProtectionDomain domain) {
PermissionCollection pc = null;
if (domain == null)
return new Permissions();
if (pdMapping == null) {
initPolicy(this);
}
synchronized (pdMapping) {
pc = pdMapping.get(domain.key);
}
if (pc != null) {
Permissions perms = new Permissions();
synchronized (pc) {
for (Enumeration<Permission> e = pc.elements() ; e.hasMoreElements() ;) {
perms.add(e.nextElement());
}
}
return perms;
}
pc = getPermissions(domain.getCodeSource());
if (pc == null || pc == UNSUPPORTED_EMPTY_COLLECTION) {
pc = new Permissions();
}
addStaticPerms(pc, domain.getPermissions());
return pc;
}
/**
* add static permissions to provided permission collection
*/
private void addStaticPerms(PermissionCollection perms,
PermissionCollection statics) {
if (statics != null) {
synchronized (statics) {
Enumeration<Permission> e = statics.elements();
while (e.hasMoreElements()) {
perms.add(e.nextElement());
}
}
}
}
/**
* Evaluates the global policy for the permissions granted to
* the ProtectionDomain and tests whether the permission is
* granted.
*
* @param domain the ProtectionDomain to test
* @param permission the Permission object to be tested for implication.
*
* @return true if "permission" is a proper subset of a permission
* granted to this ProtectionDomain.
*
* @see java.security.ProtectionDomain
* @since 1.4
*/
public boolean implies(ProtectionDomain domain, Permission permission) {
PermissionCollection pc;
if (pdMapping == null) {
initPolicy(this);
}
synchronized (pdMapping) {
pc = pdMapping.get(domain.key);
}
if (pc != null) {
return pc.implies(permission);
}
pc = getPermissions(domain);
if (pc == null) {
return false;
}
synchronized (pdMapping) {
// cache it
pdMapping.put(domain.key, pc);
}
return pc.implies(permission);
}
/**
* Refreshes/reloads the policy configuration. The behavior of this method
* depends on the implementation. For example, calling {@code refresh}
* on a file-based policy will cause the file to be re-read.
*
* <p> The default implementation of this method does nothing.
* This method should be overridden if a refresh operation is supported
* by the policy implementation.
*/
public void refresh() { }
/**
* This subclass is returned by the getInstance calls. All Policy calls
* are delegated to the underlying PolicySpi.
*/
private static class PolicyDelegate extends Policy {
private PolicySpi spi;
private Provider p;
private String type;
private Policy.Parameters params;
private PolicyDelegate(PolicySpi spi, Provider p,
String type, Policy.Parameters params) {
this.spi = spi;
this.p = p;
this.type = type;
this.params = params;
}
@Override public String getType() { return type; }
@Override public Policy.Parameters getParameters() { return params; }
@Override public Provider getProvider() { return p; }
@Override
public PermissionCollection getPermissions(CodeSource codesource) {
return spi.engineGetPermissions(codesource);
}
@Override
public PermissionCollection getPermissions(ProtectionDomain domain) {
return spi.engineGetPermissions(domain);
}
@Override
public boolean implies(ProtectionDomain domain, Permission perm) {
return spi.engineImplies(domain, perm);
}
@Override
public void refresh() {
spi.engineRefresh();
}
}
/**
* This represents a marker interface for Policy parameters.
*
* @since 1.6
*/
public static interface Parameters { }
/**
* This class represents a read-only empty PermissionCollection object that
* is returned from the {@code getPermissions(CodeSource)} and
* {@code getPermissions(ProtectionDomain)}
* methods in the Policy class when those operations are not
* supported by the Policy implementation.
*/
private static class UnsupportedEmptyCollection
extends PermissionCollection {
private static final long serialVersionUID = -8492269157353014774L;
private Permissions perms;
/**
* Create a read-only empty PermissionCollection object.
*/
public UnsupportedEmptyCollection() {
this.perms = new Permissions();
perms.setReadOnly();
}
/**
* Adds a permission object to the current collection of permission
* objects.
*
* @param permission the Permission object to add.
*
* @exception SecurityException - if this PermissionCollection object
* has been marked readonly
*/
@Override public void add(Permission permission) {
perms.add(permission);
}
/**
* Checks to see if the specified permission is implied by the
* collection of Permission objects held in this PermissionCollection.
*
* @param permission the Permission object to compare.
*
* @return true if "permission" is implied by the permissions in
* the collection, false if not.
*/
@Override public boolean implies(Permission permission) {
return perms.implies(permission);
}
/**
* Returns an enumeration of all the Permission objects in the
* collection.
*
* @return an enumeration of all the Permissions.
*/
@Override public Enumeration<Permission> elements() {
return perms.elements();
}
}
}

View file

@ -0,0 +1,118 @@
/*
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
/**
* This class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
* for the {@code Policy} class.
* All the abstract methods in this class must be implemented by each
* service provider who wishes to supply a Policy implementation.
*
* <p> Subclass implementations of this abstract class must provide
* a public constructor that takes a {@code Policy.Parameters}
* object as an input parameter. This constructor also must throw
* an IllegalArgumentException if it does not understand the
* {@code Policy.Parameters} input.
*
*
* @since 1.6
*/
public abstract class PolicySpi {
/**
* Check whether the policy has granted a Permission to a ProtectionDomain.
*
* @param domain the ProtectionDomain to check.
*
* @param permission check whether this permission is granted to the
* specified domain.
*
* @return boolean true if the permission is granted to the domain.
*/
protected abstract boolean engineImplies
(ProtectionDomain domain, Permission permission);
/**
* Refreshes/reloads the policy configuration. The behavior of this method
* depends on the implementation. For example, calling {@code refresh}
* on a file-based policy will cause the file to be re-read.
*
* <p> The default implementation of this method does nothing.
* This method should be overridden if a refresh operation is supported
* by the policy implementation.
*/
protected void engineRefresh() { }
/**
* Return a PermissionCollection object containing the set of
* permissions granted to the specified CodeSource.
*
* <p> The default implementation of this method returns
* Policy.UNSUPPORTED_EMPTY_COLLECTION object. This method can be
* overridden if the policy implementation can return a set of
* permissions granted to a CodeSource.
*
* @param codesource the CodeSource to which the returned
* PermissionCollection has been granted.
*
* @return a set of permissions granted to the specified CodeSource.
* If this operation is supported, the returned
* set of permissions must be a new mutable instance
* and it must support heterogeneous Permission types.
* If this operation is not supported,
* Policy.UNSUPPORTED_EMPTY_COLLECTION is returned.
*/
protected PermissionCollection engineGetPermissions
(CodeSource codesource) {
return Policy.UNSUPPORTED_EMPTY_COLLECTION;
}
/**
* Return a PermissionCollection object containing the set of
* permissions granted to the specified ProtectionDomain.
*
* <p> The default implementation of this method returns
* Policy.UNSUPPORTED_EMPTY_COLLECTION object. This method can be
* overridden if the policy implementation can return a set of
* permissions granted to a ProtectionDomain.
*
* @param domain the ProtectionDomain to which the returned
* PermissionCollection has been granted.
*
* @return a set of permissions granted to the specified ProtectionDomain.
* If this operation is supported, the returned
* set of permissions must be a new mutable instance
* and it must support heterogeneous Permission types.
* If this operation is not supported,
* Policy.UNSUPPORTED_EMPTY_COLLECTION is returned.
*/
protected PermissionCollection engineGetPermissions
(ProtectionDomain domain) {
return Policy.UNSUPPORTED_EMPTY_COLLECTION;
}
}

View file

@ -0,0 +1,96 @@
/*
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
import javax.security.auth.Subject;
/**
* This interface represents the abstract notion of a principal, which
* can be used to represent any entity, such as an individual, a
* corporation, and a login id.
*
* @see java.security.cert.X509Certificate
*
* @author Li Gong
* @since 1.1
*/
public interface Principal {
/**
* Compares this principal to the specified object. Returns true
* if the object passed in matches the principal represented by
* the implementation of this interface.
*
* @param another principal to compare with.
*
* @return true if the principal passed in is the same as that
* encapsulated by this principal, and false otherwise.
*/
public boolean equals(Object another);
/**
* Returns a string representation of this principal.
*
* @return a string representation of this principal.
*/
public String toString();
/**
* Returns a hashcode for this principal.
*
* @return a hashcode for this principal.
*/
public int hashCode();
/**
* Returns the name of this principal.
*
* @return the name of this principal.
*/
public String getName();
/**
* Returns true if the specified subject is implied by this principal.
*
* @implSpec
* The default implementation of this method returns true if
* {@code subject} is non-null and contains at least one principal that
* is equal to this principal.
*
* <p>Subclasses may override this with a different implementation, if
* necessary.
*
* @param subject the {@code Subject}
* @return true if {@code subject} is non-null and is
* implied by this principal, or false otherwise.
* @since 1.8
*/
public default boolean implies(Subject subject) {
if (subject == null)
return false;
return subject.getPrincipals().contains(this);
}
}

View file

@ -0,0 +1,68 @@
/*
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
/**
* A private key.
* The purpose of this interface is to group (and provide type safety
* for) all private key interfaces.
* <p>
* Note: The specialized private key interfaces extend this interface.
* See, for example, the {@code DSAPrivateKey} interface in
* {@link java.security.interfaces}.
* <p>
* Implementations should override the default {@code destroy} and
* {@code isDestroyed} methods from the
* {@link javax.security.auth.Destroyable} interface to enable
* sensitive key information to be destroyed, cleared, or in the case
* where such information is immutable, unreferenced.
* Finally, since {@code PrivateKey} is {@code Serializable}, implementations
* should also override
* {@link java.io.ObjectOutputStream#writeObject(java.lang.Object)}
* to prevent keys that have been destroyed from being serialized.
*
* @see Key
* @see PublicKey
* @see Certificate
* @see Signature#initVerify
* @see java.security.interfaces.DSAPrivateKey
* @see java.security.interfaces.RSAPrivateKey
* @see java.security.interfaces.RSAPrivateCrtKey
*
* @author Benjamin Renaud
* @author Josh Bloch
* @since 1.1
*/
public interface PrivateKey extends Key, javax.security.auth.Destroyable {
// Declare serialVersionUID to be compatible with JDK1.1
/**
* The class fingerprint that is set to indicate serialization
* compatibility with a previous version of the class.
*/
static final long serialVersionUID = 6034044314589513430L;
}

View file

@ -0,0 +1,57 @@
/*
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
/**
* A computation to be performed with privileges enabled. The computation is
* performed by invoking {@code AccessController.doPrivileged} on the
* {@code PrivilegedAction} object. This interface is used only for
* computations that do not throw checked exceptions; computations that
* throw checked exceptions must use {@code PrivilegedExceptionAction}
* instead.
*
* @since 1.2
* @see AccessController
* @see AccessController#doPrivileged(PrivilegedAction)
* @see PrivilegedExceptionAction
*/
public interface PrivilegedAction<T> {
/**
* Performs the computation. This method will be called by
* {@code AccessController.doPrivileged} after enabling privileges.
*
* @return a class-dependent value that may represent the results of the
* computation. Each class that implements
* {@code PrivilegedAction}
* should document what (if anything) this value represents.
* @see AccessController#doPrivileged(PrivilegedAction)
* @see AccessController#doPrivileged(PrivilegedAction,
* AccessControlContext)
*/
T run();
}

View file

@ -0,0 +1,106 @@
/*
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
/**
* This exception is thrown by
* {@code doPrivileged(PrivilegedExceptionAction)} and
* {@code doPrivileged(PrivilegedExceptionAction,
* AccessControlContext context)} to indicate
* that the action being performed threw a checked exception. The exception
* thrown by the action can be obtained by calling the
* {@code getException} method. In effect, an
* {@code PrivilegedActionException} is a "wrapper"
* for an exception thrown by a privileged action.
*
* <p>As of release 1.4, this exception has been retrofitted to conform to
* the general purpose exception-chaining mechanism. The "exception thrown
* by the privileged computation" that is provided at construction time and
* accessed via the {@link #getException()} method is now known as the
* <i>cause</i>, and may be accessed via the {@link Throwable#getCause()}
* method, as well as the aforementioned "legacy method."
*
* @since 1.2
* @see PrivilegedExceptionAction
* @see AccessController#doPrivileged(PrivilegedExceptionAction)
* @see AccessController#doPrivileged(PrivilegedExceptionAction,AccessControlContext)
*/
public class PrivilegedActionException extends Exception {
// use serialVersionUID from JDK 1.2.2 for interoperability
private static final long serialVersionUID = 4724086851538908602L;
/**
* @serial
*/
private Exception exception;
/**
* Constructs a new PrivilegedActionException &quot;wrapping&quot;
* the specific Exception.
*
* @param exception The exception thrown
*/
public PrivilegedActionException(Exception exception) {
super((Throwable)null); // Disallow initCause
this.exception = exception;
}
/**
* Returns the exception thrown by the privileged computation that
* resulted in this {@code PrivilegedActionException}.
*
* <p>This method predates the general-purpose exception chaining facility.
* The {@link Throwable#getCause()} method is now the preferred means of
* obtaining this information.
*
* @return the exception thrown by the privileged computation that
* resulted in this {@code PrivilegedActionException}.
* @see PrivilegedExceptionAction
* @see AccessController#doPrivileged(PrivilegedExceptionAction)
* @see AccessController#doPrivileged(PrivilegedExceptionAction,
* AccessControlContext)
*/
public Exception getException() {
return exception;
}
/**
* Returns the cause of this exception (the exception thrown by
* the privileged computation that resulted in this
* {@code PrivilegedActionException}).
*
* @return the cause of this exception.
* @since 1.4
*/
public Throwable getCause() {
return exception;
}
public String toString() {
String s = getClass().getName();
return (exception != null) ? (s + ": " + exception.toString()) : s;
}
}

View file

@ -0,0 +1,63 @@
/*
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
/**
* A computation to be performed with privileges enabled, that throws one or
* more checked exceptions. The computation is performed by invoking
* {@code AccessController.doPrivileged} on the
* {@code PrivilegedExceptionAction} object. This interface is
* used only for computations that throw checked exceptions;
* computations that do not throw
* checked exceptions should use {@code PrivilegedAction} instead.
*
* @since 1.2
* @see AccessController
* @see AccessController#doPrivileged(PrivilegedExceptionAction)
* @see AccessController#doPrivileged(PrivilegedExceptionAction,
* AccessControlContext)
* @see PrivilegedAction
*/
public interface PrivilegedExceptionAction<T> {
/**
* Performs the computation. This method will be called by
* {@code AccessController.doPrivileged} after enabling privileges.
*
* @return a class-dependent value that may represent the results of the
* computation. Each class that implements
* {@code PrivilegedExceptionAction} should document what
* (if anything) this value represents.
* @throws Exception an exceptional condition has occurred. Each class
* that implements {@code PrivilegedExceptionAction} should
* document the exceptions that its run method can throw.
* @see AccessController#doPrivileged(PrivilegedExceptionAction)
* @see AccessController#doPrivileged(PrivilegedExceptionAction,AccessControlContext)
*/
T run() throws Exception;
}

View file

@ -0,0 +1,687 @@
/*
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import jdk.internal.misc.JavaSecurityAccess;
import jdk.internal.misc.JavaSecurityProtectionDomainAccess;
import static jdk.internal.misc.JavaSecurityProtectionDomainAccess.ProtectionDomainCache;
import jdk.internal.misc.SharedSecrets;
import sun.security.action.GetPropertyAction;
import sun.security.provider.PolicyFile;
import sun.security.util.Debug;
import sun.security.util.FilePermCompat;
import sun.security.util.SecurityConstants;
/**
* The ProtectionDomain class encapsulates the characteristics of a domain,
* which encloses a set of classes whose instances are granted a set
* of permissions when being executed on behalf of a given set of Principals.
* <p>
* A static set of permissions can be bound to a ProtectionDomain when it is
* constructed; such permissions are granted to the domain regardless of the
* Policy in force. However, to support dynamic security policies, a
* ProtectionDomain can also be constructed such that it is dynamically
* mapped to a set of permissions by the current Policy whenever a permission
* is checked.
*
* @author Li Gong
* @author Roland Schemers
* @author Gary Ellison
* @since 1.2
*/
public class ProtectionDomain {
/**
* If true, {@link #impliesWithAltFilePerm} will try to be compatible on
* FilePermission checking even if a 3rd-party Policy implementation is set.
*/
private static final boolean filePermCompatInPD =
"true".equals(GetPropertyAction.privilegedGetProperty(
"jdk.security.filePermCompat"));
private static class JavaSecurityAccessImpl implements JavaSecurityAccess {
private JavaSecurityAccessImpl() {
}
@Override
public <T> T doIntersectionPrivilege(
PrivilegedAction<T> action,
final AccessControlContext stack,
final AccessControlContext context) {
if (action == null) {
throw new NullPointerException();
}
return AccessController.doPrivileged(
action,
getCombinedACC(context, stack)
);
}
@Override
public <T> T doIntersectionPrivilege(
PrivilegedAction<T> action,
AccessControlContext context) {
return doIntersectionPrivilege(action,
AccessController.getContext(), context);
}
@Override
public ProtectionDomain[] getProtectDomains(AccessControlContext context) {
return context.getContext();
}
private static AccessControlContext getCombinedACC(
AccessControlContext context, AccessControlContext stack) {
AccessControlContext acc =
new AccessControlContext(context, stack.getCombiner(), true);
return new AccessControlContext(stack.getContext(), acc).optimize();
}
}
static {
// setup SharedSecrets to allow access to doIntersectionPrivilege
// methods and ProtectionDomain cache
SharedSecrets.setJavaSecurityAccess(new JavaSecurityAccessImpl());
SharedSecrets.setJavaSecurityProtectionDomainAccess(
new JavaSecurityProtectionDomainAccess() {
@Override
public ProtectionDomainCache getProtectionDomainCache() {
return new PDCache();
}
});
}
/**
* Used for storing ProtectionDomains as keys in a Map.
*/
static final class Key {}
/* CodeSource */
private CodeSource codesource ;
/* ClassLoader the protection domain was consed from */
private ClassLoader classloader;
/* Principals running-as within this protection domain */
private Principal[] principals;
/* the rights this protection domain is granted */
private PermissionCollection permissions;
/* if the permissions object has AllPermission */
private boolean hasAllPerm = false;
/* the PermissionCollection is static (pre 1.4 constructor)
or dynamic (via a policy refresh) */
private final boolean staticPermissions;
/*
* An object used as a key when the ProtectionDomain is stored in a Map.
*/
final Key key = new Key();
/**
* Creates a new ProtectionDomain with the given CodeSource and
* Permissions. If the permissions object is not null, then
* {@code setReadOnly()} will be called on the passed in
* Permissions object.
* <p>
* The permissions granted to this domain are static, i.e.
* invoking the {@link #staticPermissionsOnly()} method returns true.
* They contain only the ones passed to this constructor and
* the current Policy will not be consulted.
*
* @param codesource the codesource associated with this domain
* @param permissions the permissions granted to this domain
*/
public ProtectionDomain(CodeSource codesource,
PermissionCollection permissions) {
this.codesource = codesource;
if (permissions != null) {
this.permissions = permissions;
this.permissions.setReadOnly();
if (permissions instanceof Permissions &&
((Permissions)permissions).allPermission != null) {
hasAllPerm = true;
}
}
this.classloader = null;
this.principals = new Principal[0];
staticPermissions = true;
}
/**
* Creates a new ProtectionDomain qualified by the given CodeSource,
* Permissions, ClassLoader and array of Principals. If the
* permissions object is not null, then {@code setReadOnly()}
* will be called on the passed in Permissions object.
* <p>
* The permissions granted to this domain are dynamic, i.e.
* invoking the {@link #staticPermissionsOnly()} method returns false.
* They include both the static permissions passed to this constructor,
* and any permissions granted to this domain by the current Policy at the
* time a permission is checked.
* <p>
* This constructor is typically used by
* {@link SecureClassLoader ClassLoaders}
* and {@link DomainCombiner DomainCombiners} which delegate to
* {@code Policy} to actively associate the permissions granted to
* this domain. This constructor affords the
* Policy provider the opportunity to augment the supplied
* PermissionCollection to reflect policy changes.
*
* @param codesource the CodeSource associated with this domain
* @param permissions the permissions granted to this domain
* @param classloader the ClassLoader associated with this domain
* @param principals the array of Principals associated with this
* domain. The contents of the array are copied to protect against
* subsequent modification.
* @see Policy#refresh
* @see Policy#getPermissions(ProtectionDomain)
* @since 1.4
*/
public ProtectionDomain(CodeSource codesource,
PermissionCollection permissions,
ClassLoader classloader,
Principal[] principals) {
this.codesource = codesource;
if (permissions != null) {
this.permissions = permissions;
this.permissions.setReadOnly();
if (permissions instanceof Permissions &&
((Permissions)permissions).allPermission != null) {
hasAllPerm = true;
}
}
this.classloader = classloader;
this.principals = (principals != null ? principals.clone():
new Principal[0]);
staticPermissions = false;
}
/**
* Returns the CodeSource of this domain.
* @return the CodeSource of this domain which may be null.
* @since 1.2
*/
public final CodeSource getCodeSource() {
return this.codesource;
}
/**
* Returns the ClassLoader of this domain.
* @return the ClassLoader of this domain which may be null.
*
* @since 1.4
*/
public final ClassLoader getClassLoader() {
return this.classloader;
}
/**
* Returns an array of principals for this domain.
* @return a non-null array of principals for this domain.
* Returns a new array each time this method is called.
*
* @since 1.4
*/
public final Principal[] getPrincipals() {
return this.principals.clone();
}
/**
* Returns the static permissions granted to this domain.
*
* @return the static set of permissions for this domain which may be null.
* @see Policy#refresh
* @see Policy#getPermissions(ProtectionDomain)
*/
public final PermissionCollection getPermissions() {
return permissions;
}
/**
* Returns true if this domain contains only static permissions
* and does not check the current {@code Policy} at the time of
* permission checking.
*
* @return true if this domain contains only static permissions.
*
* @since 9
*/
public final boolean staticPermissionsOnly() {
return this.staticPermissions;
}
/**
* Check and see if this ProtectionDomain implies the permissions
* expressed in the Permission object.
* <p>
* The set of permissions evaluated is a function of whether the
* ProtectionDomain was constructed with a static set of permissions
* or it was bound to a dynamically mapped set of permissions.
* <p>
* If the {@link #staticPermissionsOnly()} method returns
* true, then the permission will only be checked against the
* PermissionCollection supplied at construction.
* <p>
* Otherwise, the permission will be checked against the combination
* of the PermissionCollection supplied at construction and
* the current Policy binding.
*
* @param perm the Permission object to check.
*
* @return true if {@code perm} is implied by this ProtectionDomain.
*/
public boolean implies(Permission perm) {
if (hasAllPerm) {
// internal permission collection already has AllPermission -
// no need to go to policy
return true;
}
if (!staticPermissions &&
Policy.getPolicyNoCheck().implies(this, perm)) {
return true;
}
if (permissions != null) {
return permissions.implies(perm);
}
return false;
}
/**
* This method has almost the same logic flow as {@link #implies} but
* it ensures some level of FilePermission compatibility after JDK-8164705.
*
* This method is called by {@link AccessControlContext#checkPermission}
* and not intended to be called by an application.
*/
boolean impliesWithAltFilePerm(Permission perm) {
// If FilePermCompat.compat is set (default value), FilePermission
// checking compatibility should be considered.
// If filePermCompatInPD is set, this method checks for alternative
// FilePermission to keep compatibility for any Policy implementation.
// When set to false (default value), implies() is called since
// the PolicyFile implementation already supports compatibility.
// If this is a subclass of ProtectionDomain, call implies()
// because most likely user has overridden it.
if (!filePermCompatInPD || !FilePermCompat.compat ||
getClass() != ProtectionDomain.class) {
return implies(perm);
}
if (hasAllPerm) {
// internal permission collection already has AllPermission -
// no need to go to policy
return true;
}
Permission p2 = null;
boolean p2Calculated = false;
if (!staticPermissions) {
Policy policy = Policy.getPolicyNoCheck();
if (policy instanceof PolicyFile) {
// The PolicyFile implementation supports compatibility
// inside and it also covers the static permissions.
return policy.implies(this, perm);
} else {
if (policy.implies(this, perm)) {
return true;
}
p2 = FilePermCompat.newPermUsingAltPath(perm);
p2Calculated = true;
if (p2 != null && policy.implies(this, p2)) {
return true;
}
}
}
if (permissions != null) {
if (permissions.implies(perm)) {
return true;
} else {
if (!p2Calculated) {
p2 = FilePermCompat.newPermUsingAltPath(perm);
}
if (p2 != null) {
return permissions.implies(p2);
}
}
}
return false;
}
// called by the VM -- do not remove
boolean impliesCreateAccessControlContext() {
return implies(SecurityConstants.CREATE_ACC_PERMISSION);
}
/**
* Convert a ProtectionDomain to a String.
*/
@Override public String toString() {
String pals = "<no principals>";
if (principals != null && principals.length > 0) {
StringBuilder palBuf = new StringBuilder("(principals ");
for (int i = 0; i < principals.length; i++) {
palBuf.append(principals[i].getClass().getName() +
" \"" + principals[i].getName() +
"\"");
if (i < principals.length-1)
palBuf.append(",\n");
else
palBuf.append(")\n");
}
pals = palBuf.toString();
}
// Check if policy is set; we don't want to load
// the policy prematurely here
PermissionCollection pc = Policy.isSet() && seeAllp() ?
mergePermissions():
getPermissions();
return "ProtectionDomain "+
" "+codesource+"\n"+
" "+classloader+"\n"+
" "+pals+"\n"+
" "+pc+"\n";
}
/*
* holder class for the static field "debug" to delay its initialization
*/
private static class DebugHolder {
private static final Debug debug = Debug.getInstance("domain");
}
/**
* Return true (merge policy permissions) in the following cases:
*
* . SecurityManager is null
*
* . SecurityManager is not null,
* debug is not null,
* SecurityManager impelmentation is in bootclasspath,
* Policy implementation is in bootclasspath
* (the bootclasspath restrictions avoid recursion)
*
* . SecurityManager is not null,
* debug is null,
* caller has Policy.getPolicy permission
*/
private static boolean seeAllp() {
SecurityManager sm = System.getSecurityManager();
if (sm == null) {
return true;
} else {
if (DebugHolder.debug != null) {
if (sm.getClass().getClassLoader() == null &&
Policy.getPolicyNoCheck().getClass().getClassLoader()
== null) {
return true;
}
} else {
try {
sm.checkPermission(SecurityConstants.GET_POLICY_PERMISSION);
return true;
} catch (SecurityException se) {
// fall thru and return false
}
}
}
return false;
}
private PermissionCollection mergePermissions() {
if (staticPermissions)
return permissions;
PermissionCollection perms =
java.security.AccessController.doPrivileged
(new java.security.PrivilegedAction<>() {
public PermissionCollection run() {
Policy p = Policy.getPolicyNoCheck();
return p.getPermissions(ProtectionDomain.this);
}
});
Permissions mergedPerms = new Permissions();
int swag = 32;
int vcap = 8;
Enumeration<Permission> e;
List<Permission> pdVector = new ArrayList<>(vcap);
List<Permission> plVector = new ArrayList<>(swag);
//
// Build a vector of domain permissions for subsequent merge
if (permissions != null) {
synchronized (permissions) {
e = permissions.elements();
while (e.hasMoreElements()) {
pdVector.add(e.nextElement());
}
}
}
//
// Build a vector of Policy permissions for subsequent merge
if (perms != null) {
synchronized (perms) {
e = perms.elements();
while (e.hasMoreElements()) {
plVector.add(e.nextElement());
vcap++;
}
}
}
if (perms != null && permissions != null) {
//
// Weed out the duplicates from the policy. Unless a refresh
// has occurred since the pd was consed this should result in
// an empty vector.
synchronized (permissions) {
e = permissions.elements(); // domain vs policy
while (e.hasMoreElements()) {
Permission pdp = e.nextElement();
Class<?> pdpClass = pdp.getClass();
String pdpActions = pdp.getActions();
String pdpName = pdp.getName();
for (int i = 0; i < plVector.size(); i++) {
Permission pp = plVector.get(i);
if (pdpClass.isInstance(pp)) {
// The equals() method on some permissions
// have some side effects so this manual
// comparison is sufficient.
if (pdpName.equals(pp.getName()) &&
Objects.equals(pdpActions, pp.getActions())) {
plVector.remove(i);
break;
}
}
}
}
}
}
if (perms !=null) {
// the order of adding to merged perms and permissions
// needs to preserve the bugfix 4301064
for (int i = plVector.size()-1; i >= 0; i--) {
mergedPerms.add(plVector.get(i));
}
}
if (permissions != null) {
for (int i = pdVector.size()-1; i >= 0; i--) {
mergedPerms.add(pdVector.get(i));
}
}
return mergedPerms;
}
/**
* A cache of ProtectionDomains and their Permissions.
*
* This class stores ProtectionDomains as weak keys in a ConcurrentHashMap
* with additional support for checking and removing weak keys that are no
* longer in use. There can be cases where the permission collection may
* have a chain of strong references back to the ProtectionDomain, which
* ordinarily would prevent the entry from being removed from the map. To
* address that, we wrap the permission collection in a SoftReference so
* that it can be reclaimed by the garbage collector due to memory demand.
*/
private static class PDCache implements ProtectionDomainCache {
private final ConcurrentHashMap<WeakProtectionDomainKey,
SoftReference<PermissionCollection>>
pdMap = new ConcurrentHashMap<>();
private final ReferenceQueue<Key> queue = new ReferenceQueue<>();
@Override
public void put(ProtectionDomain pd, PermissionCollection pc) {
processQueue(queue, pdMap);
WeakProtectionDomainKey weakPd =
new WeakProtectionDomainKey(pd, queue);
pdMap.put(weakPd, new SoftReference<>(pc));
}
@Override
public PermissionCollection get(ProtectionDomain pd) {
processQueue(queue, pdMap);
WeakProtectionDomainKey weakPd = new WeakProtectionDomainKey(pd);
SoftReference<PermissionCollection> sr = pdMap.get(weakPd);
return (sr == null) ? null : sr.get();
}
/**
* Removes weak keys from the map that have been enqueued
* on the reference queue and are no longer in use.
*/
private static void processQueue(ReferenceQueue<Key> queue,
ConcurrentHashMap<? extends
WeakReference<Key>, ?> pdMap) {
Reference<? extends Key> ref;
while ((ref = queue.poll()) != null) {
pdMap.remove(ref);
}
}
}
/**
* A weak key for a ProtectionDomain.
*/
private static class WeakProtectionDomainKey extends WeakReference<Key> {
/**
* Saved value of the referent's identity hash code, to maintain
* a consistent hash code after the referent has been cleared
*/
private final int hash;
/**
* A key representing a null ProtectionDomain.
*/
private static final Key NULL_KEY = new Key();
/**
* Create a new WeakProtectionDomain with the specified domain and
* registered with a queue.
*/
WeakProtectionDomainKey(ProtectionDomain pd, ReferenceQueue<Key> rq) {
this((pd == null ? NULL_KEY : pd.key), rq);
}
WeakProtectionDomainKey(ProtectionDomain pd) {
this(pd == null ? NULL_KEY : pd.key);
}
private WeakProtectionDomainKey(Key key, ReferenceQueue<Key> rq) {
super(key, rq);
hash = key.hashCode();
}
private WeakProtectionDomainKey(Key key) {
super(key);
hash = key.hashCode();
}
/**
* Returns the identity hash code of the original referent.
*/
@Override
public int hashCode() {
return hash;
}
/**
* Returns true if the given object is an identical
* WeakProtectionDomainKey instance, or, if this object's referent
* has not been cleared and the given object is another
* WeakProtectionDomainKey instance with an identical non-null
* referent as this one.
*/
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj instanceof WeakProtectionDomainKey) {
Object referent = get();
return (referent != null) &&
(referent == ((WeakProtectionDomainKey)obj).get());
} else {
return false;
}
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,90 @@
/*
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
/**
* A runtime exception for Provider exceptions (such as
* misconfiguration errors or unrecoverable internal errors),
* which may be subclassed by Providers to
* throw specialized, provider-specific runtime errors.
*
* @author Benjamin Renaud
* @since 1.1
*/
public class ProviderException extends RuntimeException {
private static final long serialVersionUID = 5256023526693665674L;
/**
* Constructs a ProviderException with no detail message. A
* detail message is a String that describes this particular
* exception.
*/
public ProviderException() {
super();
}
/**
* Constructs a ProviderException with the specified detail
* message. A detail message is a String that describes this
* particular exception.
*
* @param s the detail message.
*/
public ProviderException(String s) {
super(s);
}
/**
* Creates a {@code ProviderException} with the specified
* detail message and cause.
*
* @param message the detail message (which is saved for later retrieval
* by the {@link #getMessage()} method).
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is permitted,
* and indicates that the cause is nonexistent or unknown.)
* @since 1.5
*/
public ProviderException(String message, Throwable cause) {
super(message, cause);
}
/**
* Creates a {@code ProviderException} with the specified cause
* and a detail message of {@code (cause==null ? null : cause.toString())}
* (which typically contains the class and detail message of
* {@code cause}).
*
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is permitted,
* and indicates that the cause is nonexistent or unknown.)
* @since 1.5
*/
public ProviderException(Throwable cause) {
super(cause);
}
}

View file

@ -0,0 +1,54 @@
/*
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
/**
* <p>A public key. This interface contains no methods or constants.
* It merely serves to group (and provide type safety for) all public key
* interfaces.
*
* Note: The specialized public key interfaces extend this interface.
* See, for example, the DSAPublicKey interface in
* {@code java.security.interfaces}.
*
* @since 1.1
* @see Key
* @see PrivateKey
* @see Certificate
* @see Signature#initVerify
* @see java.security.interfaces.DSAPublicKey
* @see java.security.interfaces.RSAPublicKey
*
*/
public interface PublicKey extends Key {
// Declare serialVersionUID to be compatible with JDK1.1
/**
* The class fingerprint that is set to indicate serialization
* compatibility with a previous version of the class.
*/
static final long serialVersionUID = 7187392471159151072L;
}

View file

@ -0,0 +1,305 @@
/*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import sun.security.util.Debug;
/**
* This class extends ClassLoader with additional support for defining
* classes with an associated code source and permissions which are
* retrieved by the system policy by default.
*
* @author Li Gong
* @author Roland Schemers
* @since 1.2
*/
public class SecureClassLoader extends ClassLoader {
/*
* If initialization succeed this is set to true and security checks will
* succeed. Otherwise the object is not initialized and the object is
* useless.
*/
private final boolean initialized;
/*
* Map that maps the CodeSource to a ProtectionDomain. The key is a
* CodeSourceKey class that uses a String instead of a URL to avoid
* potential expensive name service lookups. This does mean that URLs that
* are equivalent after nameservice lookup will be placed in separate
* ProtectionDomains; however during policy enforcement these URLs will be
* canonicalized and resolved resulting in a consistent set of granted
* permissions.
*/
private final Map<CodeSourceKey, ProtectionDomain> pdcache
= new ConcurrentHashMap<>(11);
static {
ClassLoader.registerAsParallelCapable();
}
/**
* Creates a new SecureClassLoader using the specified parent
* class loader for delegation.
*
* <p>If there is a security manager, this method first
* calls the security manager's {@code checkCreateClassLoader}
* method to ensure creation of a class loader is allowed.
*
* @param parent the parent ClassLoader
* @exception SecurityException if a security manager exists and its
* {@code checkCreateClassLoader} method doesn't allow
* creation of a class loader.
* @see SecurityManager#checkCreateClassLoader
*/
protected SecureClassLoader(ClassLoader parent) {
super(parent);
// this is to make the stack depth consistent with 1.1
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkCreateClassLoader();
}
initialized = true;
}
/**
* Creates a new SecureClassLoader using the default parent class
* loader for delegation.
*
* <p>If there is a security manager, this method first
* calls the security manager's {@code checkCreateClassLoader}
* method to ensure creation of a class loader is allowed.
*
* @exception SecurityException if a security manager exists and its
* {@code checkCreateClassLoader} method doesn't allow
* creation of a class loader.
* @see SecurityManager#checkCreateClassLoader
*/
protected SecureClassLoader() {
super();
// this is to make the stack depth consistent with 1.1
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkCreateClassLoader();
}
initialized = true;
}
/**
* Creates a new {@code SecureClassLoader} of the specified name and
* using the specified parent class loader for delegation.
*
* @param name class loader name; or {@code null} if not named
* @param parent the parent class loader
*
* @throws IllegalArgumentException if the given name is empty.
*
* @throws SecurityException if a security manager exists and its
* {@link SecurityManager#checkCreateClassLoader()} method
* doesn't allow creation of a class loader.
*
* @since 9
* @spec JPMS
*/
protected SecureClassLoader(String name, ClassLoader parent) {
super(name, parent);
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkCreateClassLoader();
}
initialized = true;
}
/**
* Converts an array of bytes into an instance of class Class,
* with an optional CodeSource. Before the
* class can be used it must be resolved.
* <p>
* If a non-null CodeSource is supplied a ProtectionDomain is
* constructed and associated with the class being defined.
*
* @param name the expected name of the class, or {@code null}
* if not known, using '.' and not '/' as the separator
* and without a trailing ".class" suffix.
* @param b the bytes that make up the class data. The bytes in
* positions {@code off} through {@code off+len-1}
* should have the format of a valid class file as defined by
* <cite>The Java&trade; Virtual Machine Specification</cite>.
* @param off the start offset in {@code b} of the class data
* @param len the length of the class data
* @param cs the associated CodeSource, or {@code null} if none
* @return the {@code Class} object created from the data,
* and optional CodeSource.
* @exception ClassFormatError if the data did not contain a valid class
* @exception IndexOutOfBoundsException if either {@code off} or
* {@code len} is negative, or if
* {@code off+len} is greater than {@code b.length}.
*
* @exception SecurityException if an attempt is made to add this class
* to a package that contains classes that were signed by
* a different set of certificates than this class, or if
* the class name begins with "java.".
*/
protected final Class<?> defineClass(String name,
byte[] b, int off, int len,
CodeSource cs)
{
return defineClass(name, b, off, len, getProtectionDomain(cs));
}
/**
* Converts a {@link java.nio.ByteBuffer ByteBuffer}
* into an instance of class {@code Class}, with an optional CodeSource.
* Before the class can be used it must be resolved.
* <p>
* If a non-null CodeSource is supplied a ProtectionDomain is
* constructed and associated with the class being defined.
*
* @param name the expected name of the class, or {@code null}
* if not known, using '.' and not '/' as the separator
* and without a trailing ".class" suffix.
* @param b the bytes that make up the class data. The bytes from positions
* {@code b.position()} through {@code b.position() + b.limit() -1}
* should have the format of a valid class file as defined by
* <cite>The Java&trade; Virtual Machine Specification</cite>.
* @param cs the associated CodeSource, or {@code null} if none
* @return the {@code Class} object created from the data,
* and optional CodeSource.
* @exception ClassFormatError if the data did not contain a valid class
* @exception SecurityException if an attempt is made to add this class
* to a package that contains classes that were signed by
* a different set of certificates than this class, or if
* the class name begins with "java.".
*
* @since 1.5
*/
protected final Class<?> defineClass(String name, java.nio.ByteBuffer b,
CodeSource cs)
{
return defineClass(name, b, getProtectionDomain(cs));
}
/**
* Returns the permissions for the given CodeSource object.
* <p>
* This method is invoked by the defineClass method which takes
* a CodeSource as an argument when it is constructing the
* ProtectionDomain for the class being defined.
*
* @param codesource the codesource.
*
* @return the permissions granted to the codesource.
*
*/
protected PermissionCollection getPermissions(CodeSource codesource)
{
check();
return new Permissions(); // ProtectionDomain defers the binding
}
/*
* holder class for the static field "debug" to delay its initialization
*/
private static class DebugHolder {
private static final Debug debug = Debug.getInstance("scl");
}
/*
* Returned cached ProtectionDomain for the specified CodeSource.
*/
private ProtectionDomain getProtectionDomain(CodeSource cs) {
if (cs == null) {
return null;
}
// Use a CodeSourceKey object key. It should behave in the
// same manner as the CodeSource when compared for equality except
// that no nameservice lookup is done on the hostname (String comparison
// only), and the fragment is not considered.
CodeSourceKey key = new CodeSourceKey(cs);
return pdcache.computeIfAbsent(key, new Function<>() {
@Override
public ProtectionDomain apply(CodeSourceKey key /* not used */) {
PermissionCollection perms
= SecureClassLoader.this.getPermissions(cs);
ProtectionDomain pd = new ProtectionDomain(
cs, perms, SecureClassLoader.this, null);
if (DebugHolder.debug != null) {
DebugHolder.debug.println(" getPermissions " + pd);
DebugHolder.debug.println("");
}
return pd;
}
});
}
/*
* Check to make sure the class loader has been initialized.
*/
private void check() {
if (!initialized) {
throw new SecurityException("ClassLoader object not initialized");
}
}
private static class CodeSourceKey {
private final CodeSource cs;
CodeSourceKey(CodeSource cs) {
this.cs = cs;
}
@Override
public int hashCode() {
String locationNoFrag = cs.getLocationNoFragString();
return locationNoFrag != null ? locationNoFrag.hashCode() : 0;
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof CodeSourceKey)) {
return false;
}
CodeSourceKey csk = (CodeSourceKey) obj;
if (!Objects.equals(cs.getLocationNoFragString(),
csk.cs.getLocationNoFragString())) {
return false;
}
return cs.matchCerts(csk.cs, true);
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,39 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
/**
* A marker interface for parameters used in various {@code SecureRandom}
* methods.
* <p>
* Some {@code SecureRandom} implementations might require additional
* operational parameters. Objects of classes which implement this interface
* can be passed to those implementations that support them.
*
* @see DrbgParameters
* @since 9
*/
public interface SecureRandomParameters {
}

View file

@ -0,0 +1,219 @@
/*
* Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
/**
* This class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
* for the {@link SecureRandom} class.
* <p>
* All the abstract methods in this class must be implemented by each
* service provider who wishes to supply the implementation
* of a cryptographically strong pseudo-random number generator.
*
* @implSpec
* If the {@link #SecureRandomSpi(SecureRandomParameters)}
* constructor is overridden in an implementation, it will always be called
* whenever a {@code SecureRandom} is instantiated. Precisely, if an object is
* instantiated with one of {@code SecureRandom}'s {@code getInstance} methods
* <em>without</em> a {@link SecureRandomParameters} parameter,
* the constructor will be called with a {@code null} argument and the
* implementation is responsible for creating its own
* {@code SecureRandomParameters} parameter for use when
* {@link #engineGetParameters()} is called. If an object
* is instantiated with one of {@code SecureRandom}'s {@code getInstance}
* methods <em>with</em> a {@code SecureRandomParameters} argument,
* the constructor will be called with that argument. The
* {@link #engineGetParameters()} method must not return {@code null}.
* <p>
* Otherwise, if the {@code SecureRandomSpi(SecureRandomParameters)}
* constructor is not overridden in an implementation, the
* {@link #SecureRandomSpi()} constructor must be overridden and it will be
* called if an object is instantiated with one of {@code SecureRandom}'s
* {@code getInstance} methods <em>without</em> a
* {@code SecureRandomParameters} argument. Calling one of
* {@code SecureRandom}'s {@code getInstance} methods <em>with</em>
* a {@code SecureRandomParameters} argument will never
* return an instance of this implementation. The
* {@link #engineGetParameters()} method must return {@code null}.
* <p>
* See {@link SecureRandom} for additional details on thread safety. By
* default, a {@code SecureRandomSpi} implementation is considered to be
* not safe for use by multiple concurrent threads and {@code SecureRandom}
* will synchronize access to each of the applicable engine methods
* (see {@link SecureRandom} for the list of methods). However, if a
* {@code SecureRandomSpi} implementation is thread-safe, the <a href=
* "{@docRoot}/../specs/security/standard-names.html#service-attributes">
* service provider attribute</a> "ThreadSafe" should be set to "true" during
* its registration, as follows:
* <blockquote><pre>
* put("SecureRandom.AlgName ThreadSafe", "true");</pre>
* </blockquote>
* or
* <blockquote><pre>
* putService(new Service(this, "SecureRandom", "AlgName", className,
* null, Map.of("ThreadSafe", "true")));</pre>
* </blockquote>
* {@code SecureRandom} will call the applicable engine methods
* without any synchronization.
*
* @since 1.2
*/
public abstract class SecureRandomSpi implements java.io.Serializable {
private static final long serialVersionUID = -2991854161009191830L;
/**
* Constructor without a parameter.
*/
public SecureRandomSpi() {
// ignored
}
/**
* Constructor with a parameter.
*
* @param params the {@link SecureRandomParameters} object.
* This argument can be {@code null}.
* @throws IllegalArgumentException if {@code params} is
* unrecognizable or unsupported by this {@code SecureRandom}
*
* @since 9
*/
protected SecureRandomSpi(SecureRandomParameters params) {
// ignored
}
/**
* Reseeds this random object with the given seed. The seed supplements,
* rather than replaces, the existing seed. Thus, repeated calls
* are guaranteed never to reduce randomness.
*
* @param seed the seed.
*/
protected abstract void engineSetSeed(byte[] seed);
/**
* Generates a user-specified number of random bytes.
* <p>
* Some random number generators can only generate a limited amount
* of random bytes per invocation. If the size of {@code bytes}
* is greater than this limit, the implementation should invoke
* its generation process multiple times to completely fill the
* buffer before returning from this method.
*
* @param bytes the array to be filled in with random bytes.
*/
protected abstract void engineNextBytes(byte[] bytes);
/**
* Generates a user-specified number of random bytes with
* additional parameters.
* <p>
* Some random number generators can only generate a limited amount
* of random bytes per invocation. If the size of {@code bytes}
* is greater than this limit, the implementation should invoke
* its generation process multiple times to completely fill the
* buffer before returning from this method.
*
* @implSpec The default implementation throws
* an {@link UnsupportedOperationException}.
*
* @param bytes the array to be filled in with random bytes
* @param params additional parameters
* @throws UnsupportedOperationException if the implementation
* has not overridden this method
* @throws IllegalArgumentException if {@code params} is {@code null},
* illegal or unsupported by this {@code SecureRandom}
*
* @since 9
*/
protected void engineNextBytes(
byte[] bytes, SecureRandomParameters params) {
throw new UnsupportedOperationException();
}
/**
* Returns the given number of seed bytes. This call may be used to
* seed other random number generators.
*
* @param numBytes the number of seed bytes to generate.
*
* @return the seed bytes.
*/
protected abstract byte[] engineGenerateSeed(int numBytes);
/**
* Reseeds this random object with entropy input read from its
* entropy source with additional parameters.
* <p>
* If this method is called by {@link SecureRandom#reseed()},
* {@code params} will be {@code null}.
* <p>
* Do not override this method if the implementation does not
* support reseeding.
*
* @implSpec The default implementation throws
* an {@link UnsupportedOperationException}.
*
* @param params extra parameters, can be {@code null}.
* @throws UnsupportedOperationException if the implementation
* has not overridden this method
* @throws IllegalArgumentException if {@code params} is
* illegal or unsupported by this {@code SecureRandom}
*
* @since 9
*/
protected void engineReseed(SecureRandomParameters params) {
throw new UnsupportedOperationException();
}
/**
* Returns the effective {@link SecureRandomParameters} for this
* {@code SecureRandom} instance.
*
* @implSpec The default implementation returns {@code null}.
*
* @return the effective {@link SecureRandomParameters} parameters,
* or {@code null} if no parameters were used.
*
* @since 9
*/
protected SecureRandomParameters engineGetParameters() {
return null;
}
/**
* Returns a Human-readable string representation of this
* {@code SecureRandom}.
*
* @return the string representation
*/
@Override
public String toString() {
return getClass().getSimpleName();
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,374 @@
/*
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
import java.security.*;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.StringTokenizer;
/**
* This class is for security permissions. A {@code SecurityPermission}
* contains a name (also referred to as a "target name") but no actions list;
* you either have the named permission or you don't.
* <p>
* The target name is the name of a security configuration parameter
* (see below). Currently the {@code SecurityPermission} object is used to
* guard access to the {@link AccessControlContext}, {@link Policy},
* {@link Provider}, {@link Security}, {@link Signer}, and {@link Identity}
* objects.
* <p>
* The following table lists the standard {@code SecurityPermission}
* target names, and for each provides a description of what the permission
* allows and a discussion of the risks of granting code the permission.
*
* <table class="striped">
* <caption style="display:none">target name, what the permission allows, and associated risks</caption>
* <thead>
* <tr>
* <th scope="col">Permission Target Name</th>
* <th scope="col">What the Permission Allows</th>
* <th scope="col">Risks of Allowing this Permission</th>
* </tr>
* </thead>
* <tbody>
*
* <tr>
* <th scope="row">authProvider.{provider name}</th>
* <td>Allow the named provider to be an AuthProvider for login and
* logout operations. </td>
* <td>This allows the named provider to perform login and logout
* operations. The named provider must extend {@code AuthProvider}
* and care must be taken to grant to a trusted provider since
* login operations involve sensitive authentication information
* such as PINs and passwords. </td>
* </tr>
*
* <tr>
* <th scope="row">createAccessControlContext</th>
* <td>Creation of an AccessControlContext</td>
* <td>This allows someone to instantiate an AccessControlContext
* with a {@code DomainCombiner}. Extreme care must be taken when
* granting this permission. Malicious code could create a DomainCombiner
* that augments the set of permissions granted to code, and even grant the
* code {@link java.security.AllPermission}.</td>
* </tr>
*
* <tr>
* <th scope="row">getDomainCombiner</th>
* <td>Retrieval of an AccessControlContext's DomainCombiner</td>
* <td>This allows someone to retrieve an AccessControlContext's
* {@code DomainCombiner}. Since DomainCombiners may contain
* sensitive information, this could potentially lead to a privacy leak.</td>
* </tr>
*
* <tr>
* <th scope="row">getPolicy</th>
* <td>Retrieval of the system-wide security policy (specifically, of the
* currently-installed Policy object)</td>
* <td>This allows someone to query the policy via the
* {@code getPermissions} call,
* which discloses which permissions would be granted to a given CodeSource.
* While revealing the policy does not compromise the security of
* the system, it does provide malicious code with additional information
* which it may use to better aim an attack. It is wise
* not to divulge more information than necessary.</td>
* </tr>
*
* <tr>
* <th scope="row">setPolicy</th>
* <td>Setting of the system-wide security policy (specifically,
* the Policy object)</td>
* <td>Granting this permission is extremely dangerous, as malicious
* code may grant itself all the necessary permissions it needs
* to successfully mount an attack on the system.</td>
* </tr>
*
* <tr>
* <th scope="row">createPolicy.{policy type}</th>
* <td>Getting an instance of a Policy implementation from a provider</td>
* <td>Granting this permission enables code to obtain a Policy object.
* Malicious code may query the Policy object to determine what permissions
* have been granted to code other than itself. </td>
* </tr>
*
* <tr>
* <th scope="row">getProperty.{key}</th>
* <td>Retrieval of the security property with the specified key</td>
* <td>Depending on the particular key for which access has
* been granted, the code may have access to the list of security
* providers, as well as the location of the system-wide and user
* security policies. while revealing this information does not
* compromise the security of the system, it does provide malicious
* code with additional information which it may use to better aim
* an attack.
</td>
* </tr>
*
* <tr>
* <th scope="row">setProperty.{key}</th>
* <td>Setting of the security property with the specified key</td>
* <td>This could include setting a security provider or defining
* the location of the system-wide security policy. Malicious
* code that has permission to set a new security provider may
* set a rogue provider that steals confidential information such
* as cryptographic private keys. In addition, malicious code with
* permission to set the location of the system-wide security policy
* may point it to a security policy that grants the attacker
* all the necessary permissions it requires to successfully mount
* an attack on the system.
</td>
* </tr>
*
* <tr>
* <th scope="row">insertProvider</th>
* <td>Addition of a new provider</td>
* <td>This would allow somebody to introduce a possibly
* malicious provider (e.g., one that discloses the private keys passed
* to it) as the highest-priority provider. This would be possible
* because the Security object (which manages the installed providers)
* currently does not check the integrity or authenticity of a provider
* before attaching it. The "insertProvider" permission subsumes the
* "insertProvider.{provider name}" permission (see the section below for
* more information).
* </td>
* </tr>
*
* <tr>
* <th scope="row">removeProvider.{provider name}</th>
* <td>Removal of the specified provider</td>
* <td>This may change the behavior or disable execution of other
* parts of the program. If a provider subsequently requested by the
* program has been removed, execution may fail. Also, if the removed
* provider is not explicitly requested by the rest of the program, but
* it would normally be the provider chosen when a cryptography service
* is requested (due to its previous order in the list of providers),
* a different provider will be chosen instead, or no suitable provider
* will be found, thereby resulting in program failure.</td>
* </tr>
*
* <tr>
* <th scope="row">clearProviderProperties.{provider name}</th>
* <td>"Clearing" of a Provider so that it no longer contains the properties
* used to look up services implemented by the provider</td>
* <td>This disables the lookup of services implemented by the provider.
* This may thus change the behavior or disable execution of other
* parts of the program that would normally utilize the Provider, as
* described under the "removeProvider.{provider name}" permission.</td>
* </tr>
*
* <tr>
* <th scope="row">putProviderProperty.{provider name}</th>
* <td>Setting of properties for the specified Provider</td>
* <td>The provider properties each specify the name and location
* of a particular service implemented by the provider. By granting
* this permission, you let code replace the service specification
* with another one, thereby specifying a different implementation.</td>
* </tr>
*
* <tr>
* <th scope="row">removeProviderProperty.{provider name}</th>
* <td>Removal of properties from the specified Provider</td>
* <td>This disables the lookup of services implemented by the
* provider. They are no longer accessible due to removal of the properties
* specifying their names and locations. This
* may change the behavior or disable execution of other
* parts of the program that would normally utilize the Provider, as
* described under the "removeProvider.{provider name}" permission.</td>
* </tr>
*
* </tbody>
* </table>
*
* <P>
* The following permissions have been superseded by newer permissions or are
* associated with classes that have been deprecated: {@link Identity},
* {@link IdentityScope}, {@link Signer}. Use of them is discouraged. See the
* applicable classes for more information.
*
* <table class="striped">
* <caption style="display:none">target name, what the permission allows, and associated risks</caption>
* <thead>
* <tr>
* <th scope="col">Permission Target Name</th>
* <th scope="col">What the Permission Allows</th>
* <th scope="col">Risks of Allowing this Permission</th>
* </tr>
* </thead>
*
* <tbody>
* <tr>
* <th scope="row">insertProvider.{provider name}</th>
* <td>Addition of a new provider, with the specified name</td>
* <td>Use of this permission is discouraged from further use because it is
* possible to circumvent the name restrictions by overriding the
* {@link java.security.Provider#getName} method. Also, there is an equivalent
* level of risk associated with granting code permission to insert a provider
* with a specific name, or any name it chooses. Users should use the
* "insertProvider" permission instead.
* <p>This would allow somebody to introduce a possibly
* malicious provider (e.g., one that discloses the private keys passed
* to it) as the highest-priority provider. This would be possible
* because the Security object (which manages the installed providers)
* currently does not check the integrity or authenticity of a provider
* before attaching it.</td>
* </tr>
*
* <tr>
* <th scope="row">setSystemScope</th>
* <td>Setting of the system identity scope</td>
* <td>This would allow an attacker to configure the system identity scope with
* certificates that should not be trusted, thereby granting applet or
* application code signed with those certificates privileges that
* would have been denied by the system's original identity scope.</td>
* </tr>
*
* <tr>
* <th scope="row">setIdentityPublicKey</th>
* <td>Setting of the public key for an Identity</td>
* <td>If the identity is marked as "trusted", this allows an attacker to
* introduce a different public key (e.g., its own) that is not trusted
* by the system's identity scope, thereby granting applet or
* application code signed with that public key privileges that
* would have been denied otherwise.</td>
* </tr>
*
* <tr>
* <th scope="row">setIdentityInfo</th>
* <td>Setting of a general information string for an Identity</td>
* <td>This allows attackers to set the general description for
* an identity. This may trick applications into using a different
* identity than intended or may prevent applications from finding a
* particular identity.</td>
* </tr>
*
* <tr>
* <th scope="row">addIdentityCertificate</th>
* <td>Addition of a certificate for an Identity</td>
* <td>This allows attackers to set a certificate for
* an identity's public key. This is dangerous because it affects
* the trust relationship across the system. This public key suddenly
* becomes trusted to a wider audience than it otherwise would be.</td>
* </tr>
*
* <tr>
* <th scope="row">removeIdentityCertificate</th>
* <td>Removal of a certificate for an Identity</td>
* <td>This allows attackers to remove a certificate for
* an identity's public key. This is dangerous because it affects
* the trust relationship across the system. This public key suddenly
* becomes considered less trustworthy than it otherwise would be.</td>
* </tr>
*
* <tr>
* <th scope="row">printIdentity</th>
* <td>Viewing the name of a principal
* and optionally the scope in which it is used, and whether
* or not it is considered "trusted" in that scope</td>
* <td>The scope that is printed out may be a filename, in which case
* it may convey local system information. For example, here's a sample
* printout of an identity named "carol", who is
* marked not trusted in the user's identity database:<br>
* carol[/home/luehe/identitydb.obj][not trusted]</td>
*</tr>
*
* <tr>
* <th scope="row">getSignerPrivateKey</th>
* <td>Retrieval of a Signer's private key</td>
* <td>It is very dangerous to allow access to a private key; private
* keys are supposed to be kept secret. Otherwise, code can use the
* private key to sign various files and claim the signature came from
* the Signer.</td>
* </tr>
*
* <tr>
* <th scope="row">setSignerKeyPair</th>
* <td>Setting of the key pair (public key and private key) for a Signer</td>
* <td>This would allow an attacker to replace somebody else's (the "target's")
* keypair with a possibly weaker keypair (e.g., a keypair of a smaller
* keysize). This also would allow the attacker to listen in on encrypted
* communication between the target and its peers. The target's peers
* might wrap an encryption session key under the target's "new" public
* key, which would allow the attacker (who possesses the corresponding
* private key) to unwrap the session key and decipher the communication
* data encrypted under that session key.</td>
* </tr>
*
* </tbody>
* </table>
*
* @implNote
* Implementations may define additional target names, but should use naming
* conventions such as reverse domain name notation to avoid name clashes.
*
* @see java.security.BasicPermission
* @see java.security.Permission
* @see java.security.Permissions
* @see java.security.PermissionCollection
* @see java.lang.SecurityManager
*
*
* @author Marianne Mueller
* @author Roland Schemers
* @since 1.2
*/
public final class SecurityPermission extends BasicPermission {
private static final long serialVersionUID = 5236109936224050470L;
/**
* Creates a new SecurityPermission with the specified name.
* The name is the symbolic name of the SecurityPermission. An asterisk
* may appear at the end of the name, following a ".", or by itself, to
* signify a wildcard match.
*
* @param name the name of the SecurityPermission
*
* @throws NullPointerException if {@code name} is {@code null}.
* @throws IllegalArgumentException if {@code name} is empty.
*/
public SecurityPermission(String name)
{
super(name);
}
/**
* Creates a new SecurityPermission object with the specified name.
* The name is the symbolic name of the SecurityPermission, and the
* actions String is currently unused and should be null.
*
* @param name the name of the SecurityPermission
* @param actions should be null.
*
* @throws NullPointerException if {@code name} is {@code null}.
* @throws IllegalArgumentException if {@code name} is empty.
*/
public SecurityPermission(String name, String actions)
{
super(name, actions);
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,88 @@
/*
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
/**
* This is the generic Signature exception.
*
* @author Benjamin Renaud
* @since 1.1
*/
public class SignatureException extends GeneralSecurityException {
private static final long serialVersionUID = 7509989324975124438L;
/**
* Constructs a SignatureException with no detail message. A
* detail message is a String that describes this particular
* exception.
*/
public SignatureException() {
super();
}
/**
* Constructs a SignatureException with the specified detail
* message. A detail message is a String that describes this
* particular exception.
*
* @param msg the detail message.
*/
public SignatureException(String msg) {
super(msg);
}
/**
* Creates a {@code SignatureException} with the specified
* detail message and cause.
*
* @param message the detail message (which is saved for later retrieval
* by the {@link #getMessage()} method).
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is permitted,
* and indicates that the cause is nonexistent or unknown.)
* @since 1.5
*/
public SignatureException(String message, Throwable cause) {
super(message, cause);
}
/**
* Creates a {@code SignatureException} with the specified cause
* and a detail message of {@code (cause==null ? null : cause.toString())}
* (which typically contains the class and detail message of
* {@code cause}).
*
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is permitted,
* and indicates that the cause is nonexistent or unknown.)
* @since 1.5
*/
public SignatureException(Throwable cause) {
super(cause);
}
}

View file

@ -0,0 +1,391 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
import java.security.spec.AlgorithmParameterSpec;
import java.util.*;
import java.io.*;
import java.nio.ByteBuffer;
import sun.security.jca.JCAUtil;
/**
* This class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
* for the {@code Signature} class, which is used to provide the
* functionality of a digital signature algorithm. Digital signatures are used
* for authentication and integrity assurance of digital data.
*
* <p> All the abstract methods in this class must be implemented by each
* cryptographic service provider who wishes to supply the implementation
* of a particular signature algorithm.
*
* @author Benjamin Renaud
* @since 1.2
*
*
* @see Signature
*/
public abstract class SignatureSpi {
/**
* Application-specified source of randomness.
*/
protected SecureRandom appRandom = null;
/**
* Initializes this signature object with the specified
* public key for verification operations.
*
* @param publicKey the public key of the identity whose signature is
* going to be verified.
*
* @exception InvalidKeyException if the key is improperly
* encoded, parameters are missing, and so on.
*/
protected abstract void engineInitVerify(PublicKey publicKey)
throws InvalidKeyException;
/**
* Initializes this signature object with the specified
* private key for signing operations.
*
* @param privateKey the private key of the identity whose signature
* will be generated.
*
* @exception InvalidKeyException if the key is improperly
* encoded, parameters are missing, and so on.
*/
protected abstract void engineInitSign(PrivateKey privateKey)
throws InvalidKeyException;
/**
* Initializes this signature object with the specified
* private key and source of randomness for signing operations.
*
* <p>This concrete method has been added to this previously-defined
* abstract class. (For backwards compatibility, it cannot be abstract.)
*
* @param privateKey the private key of the identity whose signature
* will be generated.
* @param random the source of randomness
*
* @exception InvalidKeyException if the key is improperly
* encoded, parameters are missing, and so on.
*/
protected void engineInitSign(PrivateKey privateKey,
SecureRandom random)
throws InvalidKeyException {
this.appRandom = random;
engineInitSign(privateKey);
}
/**
* Updates the data to be signed or verified
* using the specified byte.
*
* @param b the byte to use for the update.
*
* @exception SignatureException if the engine is not initialized
* properly.
*/
protected abstract void engineUpdate(byte b) throws SignatureException;
/**
* Updates the data to be signed or verified, using the
* specified array of bytes, starting at the specified offset.
*
* @param b the array of bytes
* @param off the offset to start from in the array of bytes
* @param len the number of bytes to use, starting at offset
*
* @exception SignatureException if the engine is not initialized
* properly
*/
protected abstract void engineUpdate(byte[] b, int off, int len)
throws SignatureException;
/**
* Updates the data to be signed or verified using the specified
* ByteBuffer. Processes the {@code data.remaining()} bytes
* starting at {@code data.position()}.
* Upon return, the buffer's position will be equal to its limit;
* its limit will not have changed.
*
* @param input the ByteBuffer
* @since 1.5
*/
protected void engineUpdate(ByteBuffer input) {
if (input.hasRemaining() == false) {
return;
}
try {
if (input.hasArray()) {
byte[] b = input.array();
int ofs = input.arrayOffset();
int pos = input.position();
int lim = input.limit();
engineUpdate(b, ofs + pos, lim - pos);
input.position(lim);
} else {
int len = input.remaining();
byte[] b = new byte[JCAUtil.getTempArraySize(len)];
while (len > 0) {
int chunk = Math.min(len, b.length);
input.get(b, 0, chunk);
engineUpdate(b, 0, chunk);
len -= chunk;
}
}
} catch (SignatureException e) {
// is specified to only occur when the engine is not initialized
// this case should never occur as it is caught in Signature.java
throw new ProviderException("update() failed", e);
}
}
/**
* Returns the signature bytes of all the data
* updated so far.
* The format of the signature depends on the underlying
* signature scheme.
*
* @return the signature bytes of the signing operation's result.
*
* @exception SignatureException if the engine is not
* initialized properly or if this signature algorithm is unable to
* process the input data provided.
*/
protected abstract byte[] engineSign() throws SignatureException;
/**
* Finishes this signature operation and stores the resulting signature
* bytes in the provided buffer {@code outbuf}, starting at
* {@code offset}.
* The format of the signature depends on the underlying
* signature scheme.
*
* <p>The signature implementation is reset to its initial state
* (the state it was in after a call to one of the
* {@code engineInitSign} methods)
* and can be reused to generate further signatures with the same private
* key.
*
* This method should be abstract, but we leave it concrete for
* binary compatibility. Knowledgeable providers should override this
* method.
*
* @param outbuf buffer for the signature result.
*
* @param offset offset into {@code outbuf} where the signature is
* stored.
*
* @param len number of bytes within {@code outbuf} allotted for the
* signature.
* Both this default implementation and the SUN provider do not
* return partial digests. If the value of this parameter is less
* than the actual signature length, this method will throw a
* SignatureException.
* This parameter is ignored if its value is greater than or equal to
* the actual signature length.
*
* @return the number of bytes placed into {@code outbuf}
*
* @exception SignatureException if the engine is not
* initialized properly, if this signature algorithm is unable to
* process the input data provided, or if {@code len} is less
* than the actual signature length.
*
* @since 1.2
*/
protected int engineSign(byte[] outbuf, int offset, int len)
throws SignatureException {
byte[] sig = engineSign();
if (len < sig.length) {
throw new SignatureException
("partial signatures not returned");
}
if (outbuf.length - offset < sig.length) {
throw new SignatureException
("insufficient space in the output buffer to store the "
+ "signature");
}
System.arraycopy(sig, 0, outbuf, offset, sig.length);
return sig.length;
}
/**
* Verifies the passed-in signature.
*
* @param sigBytes the signature bytes to be verified.
*
* @return true if the signature was verified, false if not.
*
* @exception SignatureException if the engine is not
* initialized properly, the passed-in signature is improperly
* encoded or of the wrong type, if this signature algorithm is unable to
* process the input data provided, etc.
*/
protected abstract boolean engineVerify(byte[] sigBytes)
throws SignatureException;
/**
* Verifies the passed-in signature in the specified array
* of bytes, starting at the specified offset.
*
* <p> Note: Subclasses should overwrite the default implementation.
*
*
* @param sigBytes the signature bytes to be verified.
* @param offset the offset to start from in the array of bytes.
* @param length the number of bytes to use, starting at offset.
*
* @return true if the signature was verified, false if not.
*
* @exception SignatureException if the engine is not
* initialized properly, the passed-in signature is improperly
* encoded or of the wrong type, if this signature algorithm is unable to
* process the input data provided, etc.
* @since 1.4
*/
protected boolean engineVerify(byte[] sigBytes, int offset, int length)
throws SignatureException {
byte[] sigBytesCopy = new byte[length];
System.arraycopy(sigBytes, offset, sigBytesCopy, 0, length);
return engineVerify(sigBytesCopy);
}
/**
* Sets the specified algorithm parameter to the specified
* value. This method supplies a general-purpose mechanism through
* which it is possible to set the various parameters of this object.
* A parameter may be any settable parameter for the algorithm, such as
* a parameter size, or a source of random bits for signature generation
* (if appropriate), or an indication of whether or not to perform
* a specific but optional computation. A uniform algorithm-specific
* naming scheme for each parameter is desirable but left unspecified
* at this time.
*
* @param param the string identifier of the parameter.
*
* @param value the parameter value.
*
* @exception InvalidParameterException if {@code param} is an
* invalid parameter for this signature algorithm engine,
* the parameter is already set
* and cannot be set again, a security exception occurs, and so on.
*
* @deprecated Replaced by {@link
* #engineSetParameter(java.security.spec.AlgorithmParameterSpec)
* engineSetParameter}.
*/
@Deprecated
protected abstract void engineSetParameter(String param, Object value)
throws InvalidParameterException;
/**
* <p>This method is overridden by providers to initialize
* this signature engine with the specified parameter set.
*
* @param params the parameters
*
* @exception UnsupportedOperationException if this method is not
* overridden by a provider
*
* @exception InvalidAlgorithmParameterException if this method is
* overridden by a provider and the given parameters
* are inappropriate for this signature engine
*/
protected void engineSetParameter(AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException {
throw new UnsupportedOperationException();
}
/**
* <p>This method is overridden by providers to return the
* parameters used with this signature engine, or null
* if this signature engine does not use any parameters.
*
* <p>The returned parameters may be the same that were used to initialize
* this signature engine, or may contain a combination of default and
* randomly generated parameter values used by the underlying signature
* implementation if this signature engine requires algorithm parameters
* but was not initialized with any.
*
* @return the parameters used with this signature engine, or null if this
* signature engine does not use any parameters
*
* @exception UnsupportedOperationException if this method is
* not overridden by a provider
* @since 1.4
*/
protected AlgorithmParameters engineGetParameters() {
throw new UnsupportedOperationException();
}
/**
* Gets the value of the specified algorithm parameter.
* This method supplies a general-purpose mechanism through which it
* is possible to get the various parameters of this object. A parameter
* may be any settable parameter for the algorithm, such as a parameter
* size, or a source of random bits for signature generation (if
* appropriate), or an indication of whether or not to perform a
* specific but optional computation. A uniform algorithm-specific
* naming scheme for each parameter is desirable but left unspecified
* at this time.
*
* @param param the string name of the parameter.
*
* @return the object that represents the parameter value, or null if
* there is none.
*
* @exception InvalidParameterException if {@code param} is an
* invalid parameter for this engine, or another exception occurs while
* trying to get this parameter.
*
* @deprecated
*/
@Deprecated
protected abstract Object engineGetParameter(String param)
throws InvalidParameterException;
/**
* Returns a clone if the implementation is cloneable.
*
* @return a clone if the implementation is cloneable.
*
* @exception CloneNotSupportedException if this is called
* on an implementation that does not support {@code Cloneable}.
*/
public Object clone() throws CloneNotSupportedException {
if (this instanceof Cloneable) {
return super.clone();
} else {
throw new CloneNotSupportedException();
}
}
}

View file

@ -0,0 +1,260 @@
/*
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
import java.io.*;
/**
* <p> SignedObject is a class for the purpose of creating authentic
* runtime objects whose integrity cannot be compromised without being
* detected.
*
* <p> More specifically, a SignedObject contains another Serializable
* object, the (to-be-)signed object and its signature.
*
* <p> The signed object is a "deep copy" (in serialized form) of an
* original object. Once the copy is made, further manipulation of
* the original object has no side effect on the copy.
*
* <p> The underlying signing algorithm is designated by the Signature
* object passed to the constructor and the {@code verify} method.
* A typical usage for signing is the following:
*
* <pre>{@code
* Signature signingEngine = Signature.getInstance(algorithm,
* provider);
* SignedObject so = new SignedObject(myobject, signingKey,
* signingEngine);
* }</pre>
*
* <p> A typical usage for verification is the following (having
* received SignedObject {@code so}):
*
* <pre>{@code
* Signature verificationEngine =
* Signature.getInstance(algorithm, provider);
* if (so.verify(publickey, verificationEngine))
* try {
* Object myobj = so.getObject();
* } catch (java.lang.ClassNotFoundException e) {};
* }</pre>
*
* <p> Several points are worth noting. First, there is no need to
* initialize the signing or verification engine, as it will be
* re-initialized inside the constructor and the {@code verify}
* method. Secondly, for verification to succeed, the specified
* public key must be the public key corresponding to the private key
* used to generate the SignedObject.
*
* <p> More importantly, for flexibility reasons, the
* constructor and {@code verify} method allow for
* customized signature engines, which can implement signature
* algorithms that are not installed formally as part of a crypto
* provider. However, it is crucial that the programmer writing the
* verifier code be aware what {@code Signature} engine is being
* used, as its own implementation of the {@code verify} method
* is invoked to verify a signature. In other words, a malicious
* {@code Signature} may choose to always return true on
* verification in an attempt to bypass a security check.
*
* <p> The signature algorithm can be, among others, the NIST standard
* DSA, using DSA and SHA-256. The algorithm is specified using the
* same convention as that for signatures. The DSA algorithm using the
* SHA-256 message digest algorithm can be specified, for example, as
* "SHA256withDSA". In the case of
* RSA the signing algorithm could be specified as, for example,
* "SHA256withRSA". The algorithm name must be
* specified, as there is no default.
*
* <p> The name of the Cryptography Package Provider is designated
* also by the Signature parameter to the constructor and the
* {@code verify} method. If the provider is not
* specified, the default provider is used. Each installation can
* be configured to use a particular provider as default.
*
* <p> Potential applications of SignedObject include:
* <ul>
* <li> It can be used
* internally to any Java runtime as an unforgeable authorization
* token -- one that can be passed around without the fear that the
* token can be maliciously modified without being detected.
* <li> It
* can be used to sign and serialize data/object for storage outside
* the Java runtime (e.g., storing critical access control data on
* disk).
* <li> Nested SignedObjects can be used to construct a logical
* sequence of signatures, resembling a chain of authorization and
* delegation.
* </ul>
*
* @see Signature
*
* @author Li Gong
* @since 1.2
*/
public final class SignedObject implements Serializable {
private static final long serialVersionUID = 720502720485447167L;
/*
* The original content is "deep copied" in its serialized format
* and stored in a byte array. The signature field is also in the
* form of byte array.
*/
private byte[] content;
private byte[] signature;
private String thealgorithm;
/**
* Constructs a SignedObject from any Serializable object.
* The given object is signed with the given signing key, using the
* designated signature engine.
*
* @param object the object to be signed.
* @param signingKey the private key for signing.
* @param signingEngine the signature signing engine.
*
* @exception IOException if an error occurs during serialization
* @exception InvalidKeyException if the key is invalid.
* @exception SignatureException if signing fails.
*/
public SignedObject(Serializable object, PrivateKey signingKey,
Signature signingEngine)
throws IOException, InvalidKeyException, SignatureException {
// creating a stream pipe-line, from a to b
ByteArrayOutputStream b = new ByteArrayOutputStream();
ObjectOutput a = new ObjectOutputStream(b);
// write and flush the object content to byte array
a.writeObject(object);
a.flush();
a.close();
this.content = b.toByteArray();
b.close();
// now sign the encapsulated object
this.sign(signingKey, signingEngine);
}
/**
* Retrieves the encapsulated object.
* The encapsulated object is de-serialized before it is returned.
*
* @return the encapsulated object.
*
* @exception IOException if an error occurs during de-serialization
* @exception ClassNotFoundException if an error occurs during
* de-serialization
*/
public Object getObject()
throws IOException, ClassNotFoundException
{
// creating a stream pipe-line, from b to a
ByteArrayInputStream b = new ByteArrayInputStream(this.content);
ObjectInput a = new ObjectInputStream(b);
Object obj = a.readObject();
b.close();
a.close();
return obj;
}
/**
* Retrieves the signature on the signed object, in the form of a
* byte array.
*
* @return the signature. Returns a new array each time this
* method is called.
*/
public byte[] getSignature() {
return this.signature.clone();
}
/**
* Retrieves the name of the signature algorithm.
*
* @return the signature algorithm name.
*/
public String getAlgorithm() {
return this.thealgorithm;
}
/**
* Verifies that the signature in this SignedObject is the valid
* signature for the object stored inside, with the given
* verification key, using the designated verification engine.
*
* @param verificationKey the public key for verification.
* @param verificationEngine the signature verification engine.
*
* @exception SignatureException if signature verification failed (an
* exception prevented the signature verification engine from completing
* normally).
* @exception InvalidKeyException if the verification key is invalid.
*
* @return {@code true} if the signature
* is valid, {@code false} otherwise
*/
public boolean verify(PublicKey verificationKey,
Signature verificationEngine)
throws InvalidKeyException, SignatureException {
verificationEngine.initVerify(verificationKey);
verificationEngine.update(this.content.clone());
return verificationEngine.verify(this.signature.clone());
}
/*
* Signs the encapsulated object with the given signing key, using the
* designated signature engine.
*
* @param signingKey the private key for signing.
* @param signingEngine the signature signing engine.
*
* @exception InvalidKeyException if the key is invalid.
* @exception SignatureException if signing fails.
*/
private void sign(PrivateKey signingKey, Signature signingEngine)
throws InvalidKeyException, SignatureException {
// initialize the signing engine
signingEngine.initSign(signingKey);
signingEngine.update(this.content.clone());
this.signature = signingEngine.sign().clone();
this.thealgorithm = signingEngine.getAlgorithm();
}
/**
* readObject is called to restore the state of the SignedObject from
* a stream.
*/
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
java.io.ObjectInputStream.GetField fields = s.readFields();
content = ((byte[])fields.get("content", null)).clone();
signature = ((byte[])fields.get("signature", null)).clone();
thealgorithm = (String)fields.get("thealgorithm", null);
}
}

View file

@ -0,0 +1,184 @@
/*
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
import java.io.*;
/**
* This class is used to represent an Identity that can also digitally
* sign data.
*
* <p>The management of a signer's private keys is an important and
* sensitive issue that should be handled by subclasses as appropriate
* to their intended use.
*
* @see Identity
*
* @author Benjamin Renaud
* @since 1.1
*
* @deprecated This class is no longer used. Its functionality has been
* replaced by {@code java.security.KeyStore}, the
* {@code java.security.cert} package, and
* {@code java.security.Principal}.
*/
@Deprecated(since="1.2")
public abstract class Signer extends Identity {
private static final long serialVersionUID = -1763464102261361480L;
/**
* The signer's private key.
*
* @serial
*/
private PrivateKey privateKey;
/**
* Creates a signer. This constructor should only be used for
* serialization.
*/
protected Signer() {
super();
}
/**
* Creates a signer with the specified identity name.
*
* @param name the identity name.
*/
public Signer(String name) {
super(name);
}
/**
* Creates a signer with the specified identity name and scope.
*
* @param name the identity name.
*
* @param scope the scope of the identity.
*
* @exception KeyManagementException if there is already an identity
* with the same name in the scope.
*/
public Signer(String name, IdentityScope scope)
throws KeyManagementException {
super(name, scope);
}
/**
* Returns this signer's private key.
*
* <p>First, if there is a security manager, its {@code checkSecurityAccess}
* method is called with {@code "getSignerPrivateKey"}
* as its argument to see if it's ok to return the private key.
*
* @return this signer's private key, or null if the private key has
* not yet been set.
*
* @exception SecurityException if a security manager exists and its
* {@code checkSecurityAccess} method doesn't allow
* returning the private key.
*
* @see SecurityManager#checkSecurityAccess
*/
public PrivateKey getPrivateKey() {
check("getSignerPrivateKey");
return privateKey;
}
/**
* Sets the key pair (public key and private key) for this signer.
*
* <p>First, if there is a security manager, its {@code checkSecurityAccess}
* method is called with {@code "setSignerKeyPair"}
* as its argument to see if it's ok to set the key pair.
*
* @param pair an initialized key pair.
*
* @exception InvalidParameterException if the key pair is not
* properly initialized.
* @exception KeyException if the key pair cannot be set for any
* other reason.
* @exception SecurityException if a security manager exists and its
* {@code checkSecurityAccess} method doesn't allow
* setting the key pair.
*
* @see SecurityManager#checkSecurityAccess
*/
public final void setKeyPair(KeyPair pair)
throws InvalidParameterException, KeyException {
check("setSignerKeyPair");
final PublicKey pub = pair.getPublic();
PrivateKey priv = pair.getPrivate();
if (pub == null || priv == null) {
throw new InvalidParameterException();
}
try {
AccessController.doPrivileged(
new PrivilegedExceptionAction<>() {
public Void run() throws KeyManagementException {
setPublicKey(pub);
return null;
}
});
} catch (PrivilegedActionException pae) {
throw (KeyManagementException) pae.getException();
}
privateKey = priv;
}
String printKeys() {
String keys = "";
PublicKey publicKey = getPublicKey();
if (publicKey != null && privateKey != null) {
keys = "\tpublic and private keys initialized";
} else {
keys = "\tno keys";
}
return keys;
}
/**
* Returns a string of information about the signer.
*
* @return a string of information about the signer.
*/
public String toString() {
return "[Signer]" + super.toString();
}
private static void check(String directive) {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkSecurityAccess(directive);
}
}
}

View file

@ -0,0 +1,164 @@
/*
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
import java.io.*;
import java.security.cert.Certificate;
import java.security.cert.CertPath;
import java.security.cert.X509Extension;
import java.util.Date;
import java.util.List;
/**
* This class encapsulates information about a signed timestamp.
* It is immutable.
* It includes the timestamp's date and time as well as information about the
* Timestamping Authority (TSA) which generated and signed the timestamp.
*
* @since 1.5
* @author Vincent Ryan
*/
public final class Timestamp implements Serializable {
private static final long serialVersionUID = -5502683707821851294L;
/**
* The timestamp's date and time
*
* @serial
*/
private Date timestamp;
/**
* The TSA's certificate path.
*
* @serial
*/
private CertPath signerCertPath;
/*
* Hash code for this timestamp.
*/
private transient int myhash = -1;
/**
* Constructs a Timestamp.
*
* @param timestamp is the timestamp's date and time. It must not be null.
* @param signerCertPath is the TSA's certificate path. It must not be null.
* @throws NullPointerException if timestamp or signerCertPath is null.
*/
public Timestamp(Date timestamp, CertPath signerCertPath) {
if (timestamp == null || signerCertPath == null) {
throw new NullPointerException();
}
this.timestamp = new Date(timestamp.getTime()); // clone
this.signerCertPath = signerCertPath;
}
/**
* Returns the date and time when the timestamp was generated.
*
* @return The timestamp's date and time.
*/
public Date getTimestamp() {
return new Date(timestamp.getTime()); // clone
}
/**
* Returns the certificate path for the Timestamping Authority.
*
* @return The TSA's certificate path.
*/
public CertPath getSignerCertPath() {
return signerCertPath;
}
/**
* Returns the hash code value for this timestamp.
* The hash code is generated using the date and time of the timestamp
* and the TSA's certificate path.
*
* @return a hash code value for this timestamp.
*/
public int hashCode() {
if (myhash == -1) {
myhash = timestamp.hashCode() + signerCertPath.hashCode();
}
return myhash;
}
/**
* Tests for equality between the specified object and this
* timestamp. Two timestamps are considered equal if the date and time of
* their timestamp's and their signer's certificate paths are equal.
*
* @param obj the object to test for equality with this timestamp.
*
* @return true if the timestamp are considered equal, false otherwise.
*/
public boolean equals(Object obj) {
if (obj == null || (!(obj instanceof Timestamp))) {
return false;
}
Timestamp that = (Timestamp)obj;
if (this == that) {
return true;
}
return (timestamp.equals(that.getTimestamp()) &&
signerCertPath.equals(that.getSignerCertPath()));
}
/**
* Returns a string describing this timestamp.
*
* @return A string comprising the date and time of the timestamp and
* its signer's certificate.
*/
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("(");
sb.append("timestamp: " + timestamp);
List<? extends Certificate> certs = signerCertPath.getCertificates();
if (!certs.isEmpty()) {
sb.append("TSA: " + certs.get(0));
} else {
sb.append("TSA: <empty>");
}
sb.append(")");
return sb.toString();
}
// Explicitly reset hash code value to -1
private void readObject(ObjectInputStream ois)
throws IOException, ClassNotFoundException {
ois.defaultReadObject();
myhash = -1;
timestamp = new Date(timestamp.getTime());
}
}

View file

@ -0,0 +1,63 @@
/*
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
/**
* A parameter that contains a URI pointing to data intended for a
* PolicySpi or ConfigurationSpi implementation.
*
* @since 1.6
*/
public class URIParameter implements
Policy.Parameters, javax.security.auth.login.Configuration.Parameters {
private java.net.URI uri;
/**
* Constructs a URIParameter with the URI pointing to
* data intended for an SPI implementation.
*
* @param uri the URI pointing to the data.
*
* @exception NullPointerException if the specified URI is null.
*/
public URIParameter(java.net.URI uri) {
if (uri == null) {
throw new NullPointerException("invalid null URI");
}
this.uri = uri;
}
/**
* Returns the URI.
*
* @return uri the URI.
*/
public java.net.URI getURI() {
return uri;
}
}

View file

@ -0,0 +1,56 @@
/*
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
/**
* This exception is thrown if an entry in the keystore cannot be recovered.
*
*
* @since 1.5
*/
public class UnrecoverableEntryException extends GeneralSecurityException {
private static final long serialVersionUID = -4527142945246286535L;
/**
* Constructs an UnrecoverableEntryException with no detail message.
*/
public UnrecoverableEntryException() {
super();
}
/**
* Constructs an UnrecoverableEntryException with the specified detail
* message, which provides more information about why this exception
* has been thrown.
*
* @param msg the detail message.
*/
public UnrecoverableEntryException(String msg) {
super(msg);
}
}

View file

@ -0,0 +1,56 @@
/*
* Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
/**
* This exception is thrown if a key in the keystore cannot be recovered.
*
*
* @since 1.2
*/
public class UnrecoverableKeyException extends UnrecoverableEntryException {
private static final long serialVersionUID = 7275063078190151277L;
/**
* Constructs an UnrecoverableKeyException with no detail message.
*/
public UnrecoverableKeyException() {
super();
}
/**
* Constructs an UnrecoverableKeyException with the specified detail
* message, which provides more information about why this exception
* has been thrown.
*
* @param msg the detail message.
*/
public UnrecoverableKeyException(String msg) {
super(msg);
}
}

View file

@ -0,0 +1,603 @@
/*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
import java.io.IOException;
import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.Hashtable;
import java.lang.reflect.*;
import java.security.cert.*;
/**
* The UnresolvedPermission class is used to hold Permissions that
* were "unresolved" when the Policy was initialized.
* An unresolved permission is one whose actual Permission class
* does not yet exist at the time the Policy is initialized (see below).
*
* <p>The policy for a Java runtime (specifying
* which permissions are available for code from various principals)
* is represented by a Policy object.
* Whenever a Policy is initialized or refreshed, Permission objects of
* appropriate classes are created for all permissions
* allowed by the Policy.
*
* <p>Many permission class types
* referenced by the policy configuration are ones that exist
* locally (i.e., ones that can be found on CLASSPATH).
* Objects for such permissions can be instantiated during
* Policy initialization. For example, it is always possible
* to instantiate a java.io.FilePermission, since the
* FilePermission class is found on the CLASSPATH.
*
* <p>Other permission classes may not yet exist during Policy
* initialization. For example, a referenced permission class may
* be in a JAR file that will later be loaded.
* For each such class, an UnresolvedPermission is instantiated.
* Thus, an UnresolvedPermission is essentially a "placeholder"
* containing information about the permission.
*
* <p>Later, when code calls AccessController.checkPermission
* on a permission of a type that was previously unresolved,
* but whose class has since been loaded, previously-unresolved
* permissions of that type are "resolved". That is,
* for each such UnresolvedPermission, a new object of
* the appropriate class type is instantiated, based on the
* information in the UnresolvedPermission.
*
* <p> To instantiate the new class, UnresolvedPermission assumes
* the class provides a zero, one, and/or two-argument constructor.
* The zero-argument constructor would be used to instantiate
* a permission without a name and without actions.
* A one-arg constructor is assumed to take a {@code String}
* name as input, and a two-arg constructor is assumed to take a
* {@code String} name and {@code String} actions
* as input. UnresolvedPermission may invoke a
* constructor with a {@code null} name and/or actions.
* If an appropriate permission constructor is not available,
* the UnresolvedPermission is ignored and the relevant permission
* will not be granted to executing code.
*
* <p> The newly created permission object replaces the
* UnresolvedPermission, which is removed.
*
* <p> Note that the {@code getName} method for an
* {@code UnresolvedPermission} returns the
* {@code type} (class name) for the underlying permission
* that has not been resolved.
*
* @see java.security.Permission
* @see java.security.Permissions
* @see java.security.PermissionCollection
* @see java.security.Policy
*
*
* @author Roland Schemers
* @since 1.2
*/
public final class UnresolvedPermission extends Permission
implements java.io.Serializable
{
private static final long serialVersionUID = -4821973115467008846L;
private static final sun.security.util.Debug debug =
sun.security.util.Debug.getInstance
("policy,access", "UnresolvedPermission");
/**
* The class name of the Permission class that will be
* created when this unresolved permission is resolved.
*
* @serial
*/
private String type;
/**
* The permission name.
*
* @serial
*/
private String name;
/**
* The actions of the permission.
*
* @serial
*/
private String actions;
private transient java.security.cert.Certificate[] certs;
/**
* Creates a new UnresolvedPermission containing the permission
* information needed later to actually create a Permission of the
* specified class, when the permission is resolved.
*
* @param type the class name of the Permission class that will be
* created when this unresolved permission is resolved.
* @param name the name of the permission.
* @param actions the actions of the permission.
* @param certs the certificates the permission's class was signed with.
* This is a list of certificate chains, where each chain is composed of a
* signer certificate and optionally its supporting certificate chain.
* Each chain is ordered bottom-to-top (i.e., with the signer certificate
* first and the (root) certificate authority last). The signer
* certificates are copied from the array. Subsequent changes to
* the array will not affect this UnsolvedPermission.
*/
public UnresolvedPermission(String type,
String name,
String actions,
java.security.cert.Certificate[] certs)
{
super(type);
if (type == null)
throw new NullPointerException("type can't be null");
this.type = type;
this.name = name;
this.actions = actions;
if (certs != null) {
// Extract the signer certs from the list of certificates.
for (int i=0; i<certs.length; i++) {
if (!(certs[i] instanceof X509Certificate)) {
// there is no concept of signer certs, so we store the
// entire cert array
this.certs = certs.clone();
break;
}
}
if (this.certs == null) {
// Go through the list of certs and see if all the certs are
// signer certs.
int i = 0;
int count = 0;
while (i < certs.length) {
count++;
while (((i+1) < certs.length) &&
((X509Certificate)certs[i]).getIssuerDN().equals(
((X509Certificate)certs[i+1]).getSubjectDN())) {
i++;
}
i++;
}
if (count == certs.length) {
// All the certs are signer certs, so we store the entire
// array
this.certs = certs.clone();
}
if (this.certs == null) {
// extract the signer certs
ArrayList<java.security.cert.Certificate> signerCerts =
new ArrayList<>();
i = 0;
while (i < certs.length) {
signerCerts.add(certs[i]);
while (((i+1) < certs.length) &&
((X509Certificate)certs[i]).getIssuerDN().equals(
((X509Certificate)certs[i+1]).getSubjectDN())) {
i++;
}
i++;
}
this.certs =
new java.security.cert.Certificate[signerCerts.size()];
signerCerts.toArray(this.certs);
}
}
}
}
private static final Class<?>[] PARAMS0 = { };
private static final Class<?>[] PARAMS1 = { String.class };
private static final Class<?>[] PARAMS2 = { String.class, String.class };
/**
* try and resolve this permission using the class loader of the permission
* that was passed in.
*/
Permission resolve(Permission p, java.security.cert.Certificate[] certs) {
if (this.certs != null) {
// if p wasn't signed, we don't have a match
if (certs == null) {
return null;
}
// all certs in this.certs must be present in certs
boolean match;
for (int i = 0; i < this.certs.length; i++) {
match = false;
for (int j = 0; j < certs.length; j++) {
if (this.certs[i].equals(certs[j])) {
match = true;
break;
}
}
if (!match) return null;
}
}
try {
Class<?> pc = p.getClass();
if (name == null && actions == null) {
try {
Constructor<?> c = pc.getConstructor(PARAMS0);
return (Permission)c.newInstance(new Object[] {});
} catch (NoSuchMethodException ne) {
try {
Constructor<?> c = pc.getConstructor(PARAMS1);
return (Permission) c.newInstance(
new Object[] { name});
} catch (NoSuchMethodException ne1) {
Constructor<?> c = pc.getConstructor(PARAMS2);
return (Permission) c.newInstance(
new Object[] { name, actions });
}
}
} else {
if (name != null && actions == null) {
try {
Constructor<?> c = pc.getConstructor(PARAMS1);
return (Permission) c.newInstance(
new Object[] { name});
} catch (NoSuchMethodException ne) {
Constructor<?> c = pc.getConstructor(PARAMS2);
return (Permission) c.newInstance(
new Object[] { name, actions });
}
} else {
Constructor<?> c = pc.getConstructor(PARAMS2);
return (Permission) c.newInstance(
new Object[] { name, actions });
}
}
} catch (NoSuchMethodException nsme) {
if (debug != null ) {
debug.println("NoSuchMethodException:\n could not find " +
"proper constructor for " + type);
nsme.printStackTrace();
}
return null;
} catch (Exception e) {
if (debug != null ) {
debug.println("unable to instantiate " + name);
e.printStackTrace();
}
return null;
}
}
/**
* This method always returns false for unresolved permissions.
* That is, an UnresolvedPermission is never considered to
* imply another permission.
*
* @param p the permission to check against.
*
* @return false.
*/
public boolean implies(Permission p) {
return false;
}
/**
* Checks two UnresolvedPermission objects for equality.
* Checks that {@code obj} is an UnresolvedPermission, and has
* the same type (class) name, permission name, actions, and
* certificates as this object.
*
* <p> To determine certificate equality, this method only compares
* actual signer certificates. Supporting certificate chains
* are not taken into consideration by this method.
*
* @param obj the object we are testing for equality with this object.
*
* @return true if obj is an UnresolvedPermission, and has the same
* type (class) name, permission name, actions, and
* certificates as this object.
*/
public boolean equals(Object obj) {
if (obj == this)
return true;
if (! (obj instanceof UnresolvedPermission))
return false;
UnresolvedPermission that = (UnresolvedPermission) obj;
// check type
if (!this.type.equals(that.type)) {
return false;
}
// check name
if (this.name == null) {
if (that.name != null) {
return false;
}
} else if (!this.name.equals(that.name)) {
return false;
}
// check actions
if (this.actions == null) {
if (that.actions != null) {
return false;
}
} else {
if (!this.actions.equals(that.actions)) {
return false;
}
}
// check certs
if ((this.certs == null && that.certs != null) ||
(this.certs != null && that.certs == null) ||
(this.certs != null && that.certs != null &&
this.certs.length != that.certs.length)) {
return false;
}
int i,j;
boolean match;
for (i = 0; this.certs != null && i < this.certs.length; i++) {
match = false;
for (j = 0; j < that.certs.length; j++) {
if (this.certs[i].equals(that.certs[j])) {
match = true;
break;
}
}
if (!match) return false;
}
for (i = 0; that.certs != null && i < that.certs.length; i++) {
match = false;
for (j = 0; j < this.certs.length; j++) {
if (that.certs[i].equals(this.certs[j])) {
match = true;
break;
}
}
if (!match) return false;
}
return true;
}
/**
* Returns the hash code value for this object.
*
* @return a hash code value for this object.
*/
public int hashCode() {
int hash = type.hashCode();
if (name != null)
hash ^= name.hashCode();
if (actions != null)
hash ^= actions.hashCode();
return hash;
}
/**
* Returns the canonical string representation of the actions,
* which currently is the empty string "", since there are no actions for
* an UnresolvedPermission. That is, the actions for the
* permission that will be created when this UnresolvedPermission
* is resolved may be non-null, but an UnresolvedPermission
* itself is never considered to have any actions.
*
* @return the empty string "".
*/
public String getActions()
{
return "";
}
/**
* Get the type (class name) of the underlying permission that
* has not been resolved.
*
* @return the type (class name) of the underlying permission that
* has not been resolved
*
* @since 1.5
*/
public String getUnresolvedType() {
return type;
}
/**
* Get the target name of the underlying permission that
* has not been resolved.
*
* @return the target name of the underlying permission that
* has not been resolved, or {@code null},
* if there is no target name
*
* @since 1.5
*/
public String getUnresolvedName() {
return name;
}
/**
* Get the actions for the underlying permission that
* has not been resolved.
*
* @return the actions for the underlying permission that
* has not been resolved, or {@code null}
* if there are no actions
*
* @since 1.5
*/
public String getUnresolvedActions() {
return actions;
}
/**
* Get the signer certificates (without any supporting chain)
* for the underlying permission that has not been resolved.
*
* @return the signer certificates for the underlying permission that
* has not been resolved, or null, if there are no signer certificates.
* Returns a new array each time this method is called.
*
* @since 1.5
*/
public java.security.cert.Certificate[] getUnresolvedCerts() {
return (certs == null) ? null : certs.clone();
}
/**
* Returns a string describing this UnresolvedPermission. The convention
* is to specify the class name, the permission name, and the actions, in
* the following format: '(unresolved "ClassName" "name" "actions")'.
*
* @return information about this UnresolvedPermission.
*/
public String toString() {
return "(unresolved " + type + " " + name + " " + actions + ")";
}
/**
* Returns a new PermissionCollection object for storing
* UnresolvedPermission objects.
*
* @return a new PermissionCollection object suitable for
* storing UnresolvedPermissions.
*/
public PermissionCollection newPermissionCollection() {
return new UnresolvedPermissionCollection();
}
/**
* Writes this object out to a stream (i.e., serializes it).
*
* @serialData An initial {@code String} denoting the
* {@code type} is followed by a {@code String} denoting the
* {@code name} is followed by a {@code String} denoting the
* {@code actions} is followed by an {@code int} indicating the
* number of certificates to follow
* (a value of "zero" denotes that there are no certificates associated
* with this object).
* Each certificate is written out starting with a {@code String}
* denoting the certificate type, followed by an
* {@code int} specifying the length of the certificate encoding,
* followed by the certificate encoding itself which is written out as an
* array of bytes.
*/
private void writeObject(java.io.ObjectOutputStream oos)
throws IOException
{
oos.defaultWriteObject();
if (certs==null || certs.length==0) {
oos.writeInt(0);
} else {
// write out the total number of certs
oos.writeInt(certs.length);
// write out each cert, including its type
for (int i=0; i < certs.length; i++) {
java.security.cert.Certificate cert = certs[i];
try {
oos.writeUTF(cert.getType());
byte[] encoded = cert.getEncoded();
oos.writeInt(encoded.length);
oos.write(encoded);
} catch (CertificateEncodingException cee) {
throw new IOException(cee.getMessage());
}
}
}
}
/**
* Restores this object from a stream (i.e., deserializes it).
*/
private void readObject(java.io.ObjectInputStream ois)
throws IOException, ClassNotFoundException
{
CertificateFactory cf;
Hashtable<String, CertificateFactory> cfs = null;
ois.defaultReadObject();
if (type == null)
throw new NullPointerException("type can't be null");
// process any new-style certs in the stream (if present)
int size = ois.readInt();
if (size > 0) {
// we know of 3 different cert types: X.509, PGP, SDSI, which
// could all be present in the stream at the same time
cfs = new Hashtable<>(3);
this.certs = new java.security.cert.Certificate[size];
}
for (int i=0; i<size; i++) {
// read the certificate type, and instantiate a certificate
// factory of that type (reuse existing factory if possible)
String certType = ois.readUTF();
if (cfs.containsKey(certType)) {
// reuse certificate factory
cf = cfs.get(certType);
} else {
// create new certificate factory
try {
cf = CertificateFactory.getInstance(certType);
} catch (CertificateException ce) {
throw new ClassNotFoundException
("Certificate factory for "+certType+" not found");
}
// store the certificate factory so we can reuse it later
cfs.put(certType, cf);
}
// parse the certificate
byte[] encoded=null;
try {
encoded = new byte[ois.readInt()];
} catch (OutOfMemoryError oome) {
throw new IOException("Certificate too big");
}
ois.readFully(encoded);
ByteArrayInputStream bais = new ByteArrayInputStream(encoded);
try {
this.certs[i] = cf.generateCertificate(bais);
} catch (CertificateException ce) {
throw new IOException(ce.getMessage());
}
bais.close();
}
}
}

View file

@ -0,0 +1,218 @@
/*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamField;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* A UnresolvedPermissionCollection stores a collection
* of UnresolvedPermission permissions.
*
* @see java.security.Permission
* @see java.security.Permissions
* @see java.security.UnresolvedPermission
*
*
* @author Roland Schemers
* @since 1.2
*
* @serial include
*/
final class UnresolvedPermissionCollection
extends PermissionCollection
implements java.io.Serializable
{
/**
* Key is permission type, value is a list of the UnresolvedPermissions
* of the same type.
* Not serialized; see serialization section at end of class.
*/
private transient ConcurrentHashMap<String, List<UnresolvedPermission>> perms;
/**
* Create an empty UnresolvedPermissionCollection object.
*
*/
public UnresolvedPermissionCollection() {
perms = new ConcurrentHashMap<>(11);
}
/**
* Adds a permission to this UnresolvedPermissionCollection.
* The key for the hash is the unresolved permission's type (class) name.
*
* @param permission the Permission object to add.
*/
@Override
public void add(Permission permission) {
if (! (permission instanceof UnresolvedPermission))
throw new IllegalArgumentException("invalid permission: "+
permission);
UnresolvedPermission up = (UnresolvedPermission) permission;
// Add permission to map. NOTE: cannot use lambda for
// remappingFunction parameter until JDK-8076596 is fixed.
perms.compute(up.getName(),
new java.util.function.BiFunction<>() {
@Override
public List<UnresolvedPermission> apply(String key,
List<UnresolvedPermission> oldValue) {
if (oldValue == null) {
List<UnresolvedPermission> v =
new CopyOnWriteArrayList<>();
v.add(up);
return v;
} else {
oldValue.add(up);
return oldValue;
}
}
}
);
}
/**
* get any unresolved permissions of the same type as p,
* and return the List containing them.
*/
List<UnresolvedPermission> getUnresolvedPermissions(Permission p) {
return perms.get(p.getClass().getName());
}
/**
* always returns false for unresolved permissions
*
*/
@Override
public boolean implies(Permission permission) {
return false;
}
/**
* Returns an enumeration of all the UnresolvedPermission lists in the
* container.
*
* @return an enumeration of all the UnresolvedPermission objects.
*/
@Override
public Enumeration<Permission> elements() {
List<Permission> results =
new ArrayList<>(); // where results are stored
// Get iterator of Map values (which are lists of permissions)
for (List<UnresolvedPermission> l : perms.values()) {
results.addAll(l);
}
return Collections.enumeration(results);
}
private static final long serialVersionUID = -7176153071733132400L;
// Need to maintain serialization interoperability with earlier releases,
// which had the serializable field:
// private Hashtable permissions; // keyed on type
/**
* @serialField permissions java.util.Hashtable
* A table of the UnresolvedPermissions keyed on type, value is Vector
* of permissions
*/
private static final ObjectStreamField[] serialPersistentFields = {
new ObjectStreamField("permissions", Hashtable.class),
};
/**
* @serialData Default field.
*/
/*
* Writes the contents of the perms field out as a Hashtable
* in which the values are Vectors for
* serialization compatibility with earlier releases.
*/
private void writeObject(ObjectOutputStream out) throws IOException {
// Don't call out.defaultWriteObject()
// Copy perms into a Hashtable
Hashtable<String, Vector<UnresolvedPermission>> permissions =
new Hashtable<>(perms.size()*2);
// Convert each entry (List) into a Vector
Set<Map.Entry<String, List<UnresolvedPermission>>> set = perms.entrySet();
for (Map.Entry<String, List<UnresolvedPermission>> e : set) {
// Convert list into Vector
List<UnresolvedPermission> list = e.getValue();
Vector<UnresolvedPermission> vec = new Vector<>(list);
// Add to Hashtable being serialized
permissions.put(e.getKey(), vec);
}
// Write out serializable fields
ObjectOutputStream.PutField pfields = out.putFields();
pfields.put("permissions", permissions);
out.writeFields();
}
/*
* Reads in a Hashtable in which the values are Vectors of
* UnresolvedPermissions and saves them in the perms field.
*/
private void readObject(ObjectInputStream in) throws IOException,
ClassNotFoundException {
// Don't call defaultReadObject()
// Read in serialized fields
ObjectInputStream.GetField gfields = in.readFields();
// Get permissions
@SuppressWarnings("unchecked")
// writeObject writes a Hashtable<String, Vector<UnresolvedPermission>>
// for the permissions key, so this cast is safe, unless the data is corrupt.
Hashtable<String, Vector<UnresolvedPermission>> permissions =
(Hashtable<String, Vector<UnresolvedPermission>>)
gfields.get("permissions", null);
perms = new ConcurrentHashMap<>(permissions.size()*2);
// Convert each entry (Vector) into a List
Set<Map.Entry<String, Vector<UnresolvedPermission>>> set = permissions.entrySet();
for (Map.Entry<String, Vector<UnresolvedPermission>> e : set) {
// Convert Vector into ArrayList
Vector<UnresolvedPermission> vec = e.getValue();
List<UnresolvedPermission> list = new CopyOnWriteArrayList<>(vec);
// Add to Hashtable being serialized
perms.put(e.getKey(), list);
}
}
}

View file

@ -0,0 +1,242 @@
/*
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security.acl;
import java.util.Enumeration;
import java.security.Principal;
/**
* Interface representing an Access Control List (ACL). An Access
* Control List is a data structure used to guard access to
* resources.<p>
*
* An ACL can be thought of as a data structure with multiple ACL
* entries. Each ACL entry, of interface type AclEntry, contains a
* set of permissions associated with a particular principal. (A
* principal represents an entity such as an individual user or a
* group). Additionally, each ACL entry is specified as being either
* positive or negative. If positive, the permissions are to be
* granted to the associated principal. If negative, the permissions
* are to be denied.<p>
*
* The ACL Entries in each ACL observe the following rules:
*
* <ul> <li>Each principal can have at most one positive ACL entry and
* one negative entry; that is, multiple positive or negative ACL
* entries are not allowed for any principal. Each entry specifies
* the set of permissions that are to be granted (if positive) or
* denied (if negative).
*
* <li>If there is no entry for a particular principal, then the
* principal is considered to have a null (empty) permission set.
*
* <li>If there is a positive entry that grants a principal a
* particular permission, and a negative entry that denies the
* principal the same permission, the result is as though the
* permission was never granted or denied.
*
* <li>Individual permissions always override permissions of the
* group(s) to which the individual belongs. That is, individual
* negative permissions (specific denial of permissions) override the
* groups' positive permissions. And individual positive permissions
* override the groups' negative permissions.
*
* </ul>
*
* The {@code java.security.acl } package provides the
* interfaces to the ACL and related data structures (ACL entries,
* groups, permissions, etc.).<p>
*
* The {@code java.security.acl.Acl } interface extends the
* {@code java.security.acl.Owner } interface. The Owner
* interface is used to maintain a list of owners for each ACL. Only
* owners are allowed to modify an ACL. For example, only an owner can
* call the ACL's {@code addEntry} method to add a new ACL entry
* to the ACL.
*
* @see java.security.acl.AclEntry
* @see java.security.acl.Owner
* @see java.security.acl.Acl#getPermissions
*
* @author Satish Dharmaraj
* @since 1.1
*
* @deprecated This package has been replaced by {@code java.security.Policy}
* and related classes since 1.2.
*/
@Deprecated(since="9")
public interface Acl extends Owner {
/**
* Sets the name of this ACL.
*
* @param caller the principal invoking this method. It must be an
* owner of this ACL.
*
* @param name the name to be given to this ACL.
*
* @exception NotOwnerException if the caller principal
* is not an owner of this ACL.
*
* @see #getName
*/
public void setName(Principal caller, String name)
throws NotOwnerException;
/**
* Returns the name of this ACL.
*
* @return the name of this ACL.
*
* @see #setName
*/
public String getName();
/**
* Adds an ACL entry to this ACL. An entry associates a principal
* (e.g., an individual or a group) with a set of
* permissions. Each principal can have at most one positive ACL
* entry (specifying permissions to be granted to the principal)
* and one negative ACL entry (specifying permissions to be
* denied). If there is already an ACL entry of the same type
* (negative or positive) already in the ACL, false is returned.
*
* @param caller the principal invoking this method. It must be an
* owner of this ACL.
*
* @param entry the ACL entry to be added to this ACL.
*
* @return true on success, false if an entry of the same type
* (positive or negative) for the same principal is already
* present in this ACL.
*
* @exception NotOwnerException if the caller principal
* is not an owner of this ACL.
*/
public boolean addEntry(Principal caller, AclEntry entry)
throws NotOwnerException;
/**
* Removes an ACL entry from this ACL.
*
* @param caller the principal invoking this method. It must be an
* owner of this ACL.
*
* @param entry the ACL entry to be removed from this ACL.
*
* @return true on success, false if the entry is not part of this ACL.
*
* @exception NotOwnerException if the caller principal is not
* an owner of this Acl.
*/
public boolean removeEntry(Principal caller, AclEntry entry)
throws NotOwnerException;
/**
* Returns an enumeration for the set of allowed permissions for the
* specified principal (representing an entity such as an individual or
* a group). This set of allowed permissions is calculated as
* follows:
*
* <ul>
*
* <li>If there is no entry in this Access Control List for the
* specified principal, an empty permission set is returned.
*
* <li>Otherwise, the principal's group permission sets are determined.
* (A principal can belong to one or more groups, where a group is a
* group of principals, represented by the Group interface.)
* The group positive permission set is the union of all
* the positive permissions of each group that the principal belongs to.
* The group negative permission set is the union of all
* the negative permissions of each group that the principal belongs to.
* If there is a specific permission that occurs in both
* the positive permission set and the negative permission set,
* it is removed from both.<p>
*
* The individual positive and negative permission sets are also
* determined. The positive permission set contains the permissions
* specified in the positive ACL entry (if any) for the principal.
* Similarly, the negative permission set contains the permissions
* specified in the negative ACL entry (if any) for the principal.
* The individual positive (or negative) permission set is considered
* to be null if there is not a positive (negative) ACL entry for the
* principal in this ACL.<p>
*
* The set of permissions granted to the principal is then calculated
* using the simple rule that individual permissions always override
* the group permissions. That is, the principal's individual negative
* permission set (specific denial of permissions) overrides the group
* positive permission set, and the principal's individual positive
* permission set overrides the group negative permission set.
*
* </ul>
*
* @param user the principal whose permission set is to be returned.
*
* @return the permission set specifying the permissions the principal
* is allowed.
*/
public Enumeration<Permission> getPermissions(Principal user);
/**
* Returns an enumeration of the entries in this ACL. Each element in
* the enumeration is of type AclEntry.
*
* @return an enumeration of the entries in this ACL.
*/
public Enumeration<AclEntry> entries();
/**
* Checks whether or not the specified principal has the specified
* permission. If it does, true is returned, otherwise false is returned.
*
* More specifically, this method checks whether the passed permission
* is a member of the allowed permission set of the specified principal.
* The allowed permission set is determined by the same algorithm as is
* used by the {@code getPermissions} method.
*
* @param principal the principal, assumed to be a valid authenticated
* Principal.
*
* @param permission the permission to be checked for.
*
* @return true if the principal has the specified permission, false
* otherwise.
*
* @see #getPermissions
*/
public boolean checkPermission(Principal principal, Permission permission);
/**
* Returns a string representation of the
* ACL contents.
*
* @return a string representation of the ACL contents.
*/
public String toString();
}

View file

@ -0,0 +1,159 @@
/*
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security.acl;
import java.util.Enumeration;
import java.security.Principal;
/**
* This is the interface used for representing one entry in an Access
* Control List (ACL).<p>
*
* An ACL can be thought of as a data structure with multiple ACL entry
* objects. Each ACL entry object contains a set of permissions associated
* with a particular principal. (A principal represents an entity such as
* an individual user or a group). Additionally, each ACL entry is specified
* as being either positive or negative. If positive, the permissions are
* to be granted to the associated principal. If negative, the permissions
* are to be denied. Each principal can have at most one positive ACL entry
* and one negative entry; that is, multiple positive or negative ACL
* entries are not allowed for any principal.
*
* Note: ACL entries are by default positive. An entry becomes a
* negative entry only if the
* {@link #setNegativePermissions() setNegativePermissions}
* method is called on it.
*
* @see java.security.acl.Acl
*
* @author Satish Dharmaraj
* @since 1.1
*
* @deprecated This package has been replaced by {@code java.security.Policy}
* and related classes since 1.2.
*/
@Deprecated(since="9")
public interface AclEntry extends Cloneable {
/**
* Specifies the principal for which permissions are granted or denied
* by this ACL entry. If a principal was already set for this ACL entry,
* false is returned, otherwise true is returned.
*
* @param user the principal to be set for this entry.
*
* @return true if the principal is set, false if there was
* already a principal set for this entry.
*
* @see #getPrincipal
*/
public boolean setPrincipal(Principal user);
/**
* Returns the principal for which permissions are granted or denied by
* this ACL entry. Returns null if there is no principal set for this
* entry yet.
*
* @return the principal associated with this entry.
*
* @see #setPrincipal
*/
public Principal getPrincipal();
/**
* Sets this ACL entry to be a negative one. That is, the associated
* principal (e.g., a user or a group) will be denied the permission set
* specified in the entry.
*
* Note: ACL entries are by default positive. An entry becomes a
* negative entry only if this {@code setNegativePermissions}
* method is called on it.
*/
public void setNegativePermissions();
/**
* Returns true if this is a negative ACL entry (one denying the
* associated principal the set of permissions in the entry), false
* otherwise.
*
* @return true if this is a negative ACL entry, false if it's not.
*/
public boolean isNegative();
/**
* Adds the specified permission to this ACL entry. Note: An entry can
* have multiple permissions.
*
* @param permission the permission to be associated with
* the principal in this entry.
*
* @return true if the permission was added, false if the
* permission was already part of this entry's permission set.
*/
public boolean addPermission(Permission permission);
/**
* Removes the specified permission from this ACL entry.
*
* @param permission the permission to be removed from this entry.
*
* @return true if the permission is removed, false if the
* permission was not part of this entry's permission set.
*/
public boolean removePermission(Permission permission);
/**
* Checks if the specified permission is part of the
* permission set in this entry.
*
* @param permission the permission to be checked for.
*
* @return true if the permission is part of the
* permission set in this entry, false otherwise.
*/
public boolean checkPermission(Permission permission);
/**
* Returns an enumeration of the permissions in this ACL entry.
*
* @return an enumeration of the permissions in this ACL entry.
*/
public Enumeration<Permission> permissions();
/**
* Returns a string representation of the contents of this ACL entry.
*
* @return a string representation of the contents.
*/
public String toString();
/**
* Clones this ACL entry.
*
* @return a clone of this ACL entry.
*/
public Object clone();
}

View file

@ -0,0 +1,49 @@
/*
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security.acl;
/**
* This is an exception that is thrown whenever a reference is made to a
* non-existent ACL (Access Control List).
*
* @author Satish Dharmaraj
* @since 1.1
*
* @deprecated This package has been replaced by {@code java.security.Policy}
* and related classes since 1.2.
*/
@Deprecated(since="9")
public class AclNotFoundException extends Exception {
private static final long serialVersionUID = 5684295034092681791L;
/**
* Constructs an AclNotFoundException.
*/
public AclNotFoundException() {
}
}

View file

@ -0,0 +1,92 @@
/*
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security.acl;
import java.util.Enumeration;
import java.security.Principal;
/**
* This interface is used to represent a group of principals. (A principal
* represents an entity such as an individual user or a company). <p>
*
* Note that Group extends Principal. Thus, either a Principal or a Group can
* be passed as an argument to methods containing a Principal parameter. For
* example, you can add either a Principal or a Group to a Group object by
* calling the object's {@code addMember} method, passing it the
* Principal or Group.
*
* @author Satish Dharmaraj
* @since 1.1
*
* @deprecated This package has been replaced by {@code java.security.Policy}
* and related classes since 1.2.
*/
@Deprecated(since="9")
public interface Group extends Principal {
/**
* Adds the specified member to the group.
*
* @param user the principal to add to this group.
*
* @return true if the member was successfully added,
* false if the principal was already a member.
*/
public boolean addMember(Principal user);
/**
* Removes the specified member from the group.
*
* @param user the principal to remove from this group.
*
* @return true if the principal was removed, or
* false if the principal was not a member.
*/
public boolean removeMember(Principal user);
/**
* Returns true if the passed principal is a member of the group.
* This method does a recursive search, so if a principal belongs to a
* group which is a member of this group, true is returned.
*
* @param member the principal whose membership is to be checked.
*
* @return true if the principal is a member of this group,
* false otherwise.
*/
public boolean isMember(Principal member);
/**
* Returns an enumeration of the members in the group.
* The returned objects can be instances of either Principal
* or Group (which is a subclass of Principal).
*
* @return an enumeration of the group members.
*/
public Enumeration<? extends Principal> members();
}

View file

@ -0,0 +1,50 @@
/*
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security.acl;
/**
* This is an exception that is thrown whenever an attempt is made to delete
* the last owner of an Access Control List.
*
* @see java.security.acl.Owner#deleteOwner
*
* @author Satish Dharmaraj
* @since 1.1
*
* @deprecated This package has been replaced by {@code java.security.Policy}
* and related classes since 1.2.
*/
@Deprecated(since="9")
public class LastOwnerException extends Exception {
private static final long serialVersionUID = -5141997548211140359L;
/**
* Constructs a LastOwnerException.
*/
public LastOwnerException() {
}
}

View file

@ -0,0 +1,49 @@
/*
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security.acl;
/**
* This is an exception that is thrown whenever the modification of an object
* (such as an Access Control List) is only allowed to be done by an owner of
* the object, but the Principal attempting the modification is not an owner.
*
* @author Satish Dharmaraj
* @since 1.1
*
* @deprecated This package has been replaced by {@code java.security.Policy}
* and related classes since 1.2.
*/
@Deprecated(since="9")
public class NotOwnerException extends Exception {
private static final long serialVersionUID = -5555597911163362399L;
/**
* Constructs a NotOwnerException.
*/
public NotOwnerException() {
}
}

View file

@ -0,0 +1,99 @@
/*
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security.acl;
import java.security.Principal;
/**
* Interface for managing owners of Access Control Lists (ACLs) or ACL
* configurations. (Note that the Acl interface in the
* {@code java.security.acl} package extends this Owner
* interface.) The initial owner Principal should be specified as an
* argument to the constructor of the class implementing this interface.
*
* @since 1.1
* @see java.security.acl.Acl
*
* @deprecated This package has been replaced by {@code java.security.Policy}
* and related classes since 1.2.
*/
@Deprecated(since="9")
public interface Owner {
/**
* Adds an owner. Only owners can modify ACL contents. The caller
* principal must be an owner of the ACL in order to invoke this method.
* That is, only an owner can add another owner. The initial owner is
* configured at ACL construction time.
*
* @param caller the principal invoking this method. It must be an owner
* of the ACL.
*
* @param owner the owner that should be added to the list of owners.
*
* @return true if successful, false if owner is already an owner.
* @exception NotOwnerException if the caller principal is not an owner
* of the ACL.
*/
public boolean addOwner(Principal caller, Principal owner)
throws NotOwnerException;
/**
* Deletes an owner. If this is the last owner in the ACL, an exception is
* raised.<p>
*
* The caller principal must be an owner of the ACL in order to invoke
* this method.
*
* @param caller the principal invoking this method. It must be an owner
* of the ACL.
*
* @param owner the owner to be removed from the list of owners.
*
* @return true if the owner is removed, false if the owner is not part
* of the list of owners.
*
* @exception NotOwnerException if the caller principal is not an owner
* of the ACL.
*
* @exception LastOwnerException if there is only one owner left, so that
* deleteOwner would leave the ACL owner-less.
*/
public boolean deleteOwner(Principal caller, Principal owner)
throws NotOwnerException, LastOwnerException;
/**
* Returns true if the given principal is an owner of the ACL.
*
* @param owner the principal to be checked to determine whether or not
* it is an owner.
*
* @return true if the passed principal is in the list of owners, false
* if not.
*/
public boolean isOwner(Principal owner);
}

View file

@ -0,0 +1,59 @@
/*
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security.acl;
/**
* This interface represents a permission, such as that used to grant
* a particular type of access to a resource.
*
* @author Satish Dharmaraj
* @since 1.1
*
* @deprecated This package has been replaced by {@code java.security.Policy}
* and related classes since 1.2.
*/
@Deprecated(since="9")
public interface Permission {
/**
* Returns true if the object passed matches the permission represented
* in this interface.
*
* @param another the Permission object to compare with.
*
* @return true if the Permission objects are equal, false otherwise
*/
public boolean equals(Object another);
/**
* Prints a string representation of this permission.
*
* @return the string representation of the permission.
*/
public String toString();
}

View file

@ -0,0 +1,34 @@
/*
* Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* The classes and interfaces in this package have been deprecated. New
* classes should not be added to this package. The {@code java.security}
* package contains suitable replacements. See {@link java.security.Policy}
* and related classes for details.
*
* @since 1.1
*/
package java.security.acl;

View file

@ -0,0 +1,88 @@
/*
* Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security.cert;
/**
* This class is an abstraction of certificate revocation lists (CRLs) that
* have different formats but important common uses. For example, all CRLs
* share the functionality of listing revoked certificates, and can be queried
* on whether or not they list a given certificate.
* <p>
* Specialized CRL types can be defined by subclassing off of this abstract
* class.
*
* @author Hemma Prafullchandra
*
*
* @see X509CRL
* @see CertificateFactory
*
* @since 1.2
*/
public abstract class CRL {
// the CRL type
private String type;
/**
* Creates a CRL of the specified type.
*
* @param type the standard name of the CRL type.
* See the <a href=
* "{@docRoot}/../specs/security/standard-names.html">
* Java Security Standard Algorithm Names</a> document
* for information about standard CRL types.
*/
protected CRL(String type) {
this.type = type;
}
/**
* Returns the type of this CRL.
*
* @return the type of this CRL.
*/
public final String getType() {
return this.type;
}
/**
* Returns a string representation of this CRL.
*
* @return a string representation of this CRL.
*/
public abstract String toString();
/**
* Checks whether the given certificate is on this CRL.
*
* @param cert the certificate to check for.
* @return true if the given certificate is on this CRL,
* false otherwise.
*/
public abstract boolean isRevoked(Certificate cert);
}

View file

@ -0,0 +1,89 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security.cert;
import java.security.GeneralSecurityException;
/**
* CRL (Certificate Revocation List) Exception.
*
* @author Hemma Prafullchandra
* @since 1.2
*/
public class CRLException extends GeneralSecurityException {
private static final long serialVersionUID = -6694728944094197147L;
/**
* Constructs a CRLException with no detail message. A
* detail message is a String that describes this particular
* exception.
*/
public CRLException() {
super();
}
/**
* Constructs a CRLException with the specified detail
* message. A detail message is a String that describes this
* particular exception.
*
* @param message the detail message.
*/
public CRLException(String message) {
super(message);
}
/**
* Creates a {@code CRLException} with the specified
* detail message and cause.
*
* @param message the detail message (which is saved for later retrieval
* by the {@link #getMessage()} method).
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is permitted,
* and indicates that the cause is nonexistent or unknown.)
* @since 1.5
*/
public CRLException(String message, Throwable cause) {
super(message, cause);
}
/**
* Creates a {@code CRLException} with the specified cause
* and a detail message of {@code (cause==null ? null : cause.toString())}
* (which typically contains the class and detail message of
* {@code cause}).
*
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause()} method). (A {@code null} value is permitted,
* and indicates that the cause is nonexistent or unknown.)
* @since 1.5
*/
public CRLException(Throwable cause) {
super(cause);
}
}

View file

@ -0,0 +1,104 @@
/*
* Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security.cert;
/**
* The CRLReason enumeration specifies the reason that a certificate
* is revoked, as defined in <a href="http://tools.ietf.org/html/rfc5280">
* RFC 5280: Internet X.509 Public Key Infrastructure Certificate and CRL
* Profile</a>.
*
* @author Sean Mullan
* @since 1.7
* @see X509CRLEntry#getRevocationReason
* @see CertificateRevokedException#getRevocationReason
*/
public enum CRLReason {
/**
* This reason indicates that it is unspecified as to why the
* certificate has been revoked.
*/
UNSPECIFIED,
/**
* This reason indicates that it is known or suspected that the
* certificate subject's private key has been compromised. It applies
* to end-entity certificates only.
*/
KEY_COMPROMISE,
/**
* This reason indicates that it is known or suspected that the
* certificate subject's private key has been compromised. It applies
* to certificate authority (CA) certificates only.
*/
CA_COMPROMISE,
/**
* This reason indicates that the subject's name or other information
* has changed.
*/
AFFILIATION_CHANGED,
/**
* This reason indicates that the certificate has been superseded.
*/
SUPERSEDED,
/**
* This reason indicates that the certificate is no longer needed.
*/
CESSATION_OF_OPERATION,
/**
* This reason indicates that the certificate has been put on hold.
*/
CERTIFICATE_HOLD,
/**
* Unused reason.
*/
UNUSED,
/**
* This reason indicates that the certificate was previously on hold
* and should be removed from the CRL. It is for use with delta CRLs.
*/
REMOVE_FROM_CRL,
/**
* This reason indicates that the privileges granted to the subject of
* the certificate have been withdrawn.
*/
PRIVILEGE_WITHDRAWN,
/**
* This reason indicates that it is known or suspected that the
* certificate subject's private key has been compromised. It applies
* to authority attribute (AA) certificates only.
*/
AA_COMPROMISE
}

View file

@ -0,0 +1,66 @@
/*
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security.cert;
/**
* A selector that defines a set of criteria for selecting {@code CRL}s.
* Classes that implement this interface are often used to specify
* which {@code CRL}s should be retrieved from a {@code CertStore}.
* <p>
* <b>Concurrent Access</b>
* <p>
* Unless otherwise specified, the methods defined in this interface are not
* thread-safe. Multiple threads that need to access a single
* object concurrently should synchronize amongst themselves and
* provide the necessary locking. Multiple threads each manipulating
* separate objects need not synchronize.
*
* @see CRL
* @see CertStore
* @see CertStore#getCRLs
*
* @author Steve Hanna
* @since 1.4
*/
public interface CRLSelector extends Cloneable {
/**
* Decides whether a {@code CRL} should be selected.
*
* @param crl the {@code CRL} to be checked
* @return {@code true} if the {@code CRL} should be selected,
* {@code false} otherwise
*/
boolean match(CRL crl);
/**
* Makes a copy of this {@code CRLSelector}. Changes to the
* copy will not affect the original and vice versa.
*
* @return a copy of this {@code CRLSelector}
*/
Object clone();
}

View file

@ -0,0 +1,343 @@
/*
* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security.cert;
import java.io.ByteArrayInputStream;
import java.io.NotSerializableException;
import java.io.ObjectStreamException;
import java.io.Serializable;
import java.util.Iterator;
import java.util.List;
/**
* An immutable sequence of certificates (a certification path).
* <p>
* This is an abstract class that defines the methods common to all
* {@code CertPath}s. Subclasses can handle different kinds of
* certificates (X.509, PGP, etc.).
* <p>
* All {@code CertPath} objects have a type, a list of
* {@code Certificate}s, and one or more supported encodings. Because the
* {@code CertPath} class is immutable, a {@code CertPath} cannot
* change in any externally visible way after being constructed. This
* stipulation applies to all public fields and methods of this class and any
* added or overridden by subclasses.
* <p>
* The type is a {@code String} that identifies the type of
* {@code Certificate}s in the certification path. For each
* certificate {@code cert} in a certification path {@code certPath},
* {@code cert.getType().equals(certPath.getType())} must be
* {@code true}.
* <p>
* The list of {@code Certificate}s is an ordered {@code List} of
* zero or more {@code Certificate}s. This {@code List} and all
* of the {@code Certificate}s contained in it must be immutable.
* <p>
* Each {@code CertPath} object must support one or more encodings
* so that the object can be translated into a byte array for storage or
* transmission to other parties. Preferably, these encodings should be
* well-documented standards (such as PKCS#7). One of the encodings supported
* by a {@code CertPath} is considered the default encoding. This
* encoding is used if no encoding is explicitly requested (for the
* {@link #getEncoded() getEncoded()} method, for instance).
* <p>
* All {@code CertPath} objects are also {@code Serializable}.
* {@code CertPath} objects are resolved into an alternate
* {@link CertPathRep CertPathRep} object during serialization. This allows
* a {@code CertPath} object to be serialized into an equivalent
* representation regardless of its underlying implementation.
* <p>
* {@code CertPath} objects can be created with a
* {@code CertificateFactory} or they can be returned by other classes,
* such as a {@code CertPathBuilder}.
* <p>
* By convention, X.509 {@code CertPath}s (consisting of
* {@code X509Certificate}s), are ordered starting with the target
* certificate and ending with a certificate issued by the trust anchor. That
* is, the issuer of one certificate is the subject of the following one. The
* certificate representing the {@link TrustAnchor TrustAnchor} should not be
* included in the certification path. Unvalidated X.509 {@code CertPath}s
* may not follow these conventions. PKIX {@code CertPathValidator}s will
* detect any departure from these conventions that cause the certification
* path to be invalid and throw a {@code CertPathValidatorException}.
*
* <p> Every implementation of the Java platform is required to support the
* following standard {@code CertPath} encodings:
* <ul>
* <li>{@code PKCS7}</li>
* <li>{@code PkiPath}</li>
* </ul>
* These encodings are described in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#certpath-encodings">
* CertPath Encodings section</a> of the
* Java Security Standard Algorithm Names Specification.
* Consult the release documentation for your implementation to see if any
* other encodings are supported.
* <p>
* <b>Concurrent Access</b>
* <p>
* All {@code CertPath} objects must be thread-safe. That is, multiple
* threads may concurrently invoke the methods defined in this class on a
* single {@code CertPath} object (or more than one) with no
* ill effects. This is also true for the {@code List} returned by
* {@code CertPath.getCertificates}.
* <p>
* Requiring {@code CertPath} objects to be immutable and thread-safe
* allows them to be passed around to various pieces of code without worrying
* about coordinating access. Providing this thread-safety is
* generally not difficult, since the {@code CertPath} and
* {@code List} objects in question are immutable.
*
* @see CertificateFactory
* @see CertPathBuilder
*
* @author Yassir Elley
* @since 1.4
*/
public abstract class CertPath implements Serializable {
private static final long serialVersionUID = 6068470306649138683L;
private String type; // the type of certificates in this chain
/**
* Creates a {@code CertPath} of the specified type.
* <p>
* This constructor is protected because most users should use a
* {@code CertificateFactory} to create {@code CertPath}s.
*
* @param type the standard name of the type of
* {@code Certificate}s in this path
*/
protected CertPath(String type) {
this.type = type;
}
/**
* Returns the type of {@code Certificate}s in this certification
* path. This is the same string that would be returned by
* {@link java.security.cert.Certificate#getType() cert.getType()}
* for all {@code Certificate}s in the certification path.
*
* @return the type of {@code Certificate}s in this certification
* path (never null)
*/
public String getType() {
return type;
}
/**
* Returns an iteration of the encodings supported by this certification
* path, with the default encoding first. Attempts to modify the returned
* {@code Iterator} via its {@code remove} method result in an
* {@code UnsupportedOperationException}.
*
* @return an {@code Iterator} over the names of the supported
* encodings (as Strings)
*/
public abstract Iterator<String> getEncodings();
/**
* Compares this certification path for equality with the specified
* object. Two {@code CertPath}s are equal if and only if their
* types are equal and their certificate {@code List}s (and by
* implication the {@code Certificate}s in those {@code List}s)
* are equal. A {@code CertPath} is never equal to an object that is
* not a {@code CertPath}.
* <p>
* This algorithm is implemented by this method. If it is overridden,
* the behavior specified here must be maintained.
*
* @param other the object to test for equality with this certification path
* @return true if the specified object is equal to this certification path,
* false otherwise
*/
public boolean equals(Object other) {
if (this == other)
return true;
if (! (other instanceof CertPath))
return false;
CertPath otherCP = (CertPath) other;
if (! otherCP.getType().equals(type))
return false;
List<? extends Certificate> thisCertList = this.getCertificates();
List<? extends Certificate> otherCertList = otherCP.getCertificates();
return(thisCertList.equals(otherCertList));
}
/**
* Returns the hashcode for this certification path. The hash code of
* a certification path is defined to be the result of the following
* calculation:
* <pre>{@code
* hashCode = path.getType().hashCode();
* hashCode = 31*hashCode + path.getCertificates().hashCode();
* }</pre>
* This ensures that {@code path1.equals(path2)} implies that
* {@code path1.hashCode()==path2.hashCode()} for any two certification
* paths, {@code path1} and {@code path2}, as required by the
* general contract of {@code Object.hashCode}.
*
* @return the hashcode value for this certification path
*/
public int hashCode() {
int hashCode = type.hashCode();
hashCode = 31*hashCode + getCertificates().hashCode();
return hashCode;
}
/**
* Returns a string representation of this certification path.
* This calls the {@code toString} method on each of the
* {@code Certificate}s in the path.
*
* @return a string representation of this certification path
*/
public String toString() {
StringBuilder sb = new StringBuilder();
Iterator<? extends Certificate> stringIterator =
getCertificates().iterator();
sb.append("\n" + type + " Cert Path: length = "
+ getCertificates().size() + ".\n");
sb.append("[\n");
int i = 1;
while (stringIterator.hasNext()) {
sb.append("=========================================="
+ "===============Certificate " + i + " start.\n");
Certificate stringCert = stringIterator.next();
sb.append(stringCert.toString());
sb.append("\n========================================"
+ "=================Certificate " + i + " end.\n\n\n");
i++;
}
sb.append("\n]");
return sb.toString();
}
/**
* Returns the encoded form of this certification path, using the default
* encoding.
*
* @return the encoded bytes
* @exception CertificateEncodingException if an encoding error occurs
*/
public abstract byte[] getEncoded()
throws CertificateEncodingException;
/**
* Returns the encoded form of this certification path, using the
* specified encoding.
*
* @param encoding the name of the encoding to use
* @return the encoded bytes
* @exception CertificateEncodingException if an encoding error occurs or
* the encoding requested is not supported
*/
public abstract byte[] getEncoded(String encoding)
throws CertificateEncodingException;
/**
* Returns the list of certificates in this certification path.
* The {@code List} returned must be immutable and thread-safe.
*
* @return an immutable {@code List} of {@code Certificate}s
* (may be empty, but not null)
*/
public abstract List<? extends Certificate> getCertificates();
/**
* Replaces the {@code CertPath} to be serialized with a
* {@code CertPathRep} object.
*
* @return the {@code CertPathRep} to be serialized
*
* @throws ObjectStreamException if a {@code CertPathRep} object
* representing this certification path could not be created
*/
protected Object writeReplace() throws ObjectStreamException {
try {
return new CertPathRep(type, getEncoded());
} catch (CertificateException ce) {
NotSerializableException nse =
new NotSerializableException
("java.security.cert.CertPath: " + type);
nse.initCause(ce);
throw nse;
}
}
/**
* Alternate {@code CertPath} class for serialization.
* @since 1.4
*/
protected static class CertPathRep implements Serializable {
private static final long serialVersionUID = 3015633072427920915L;
/** The Certificate type */
private String type;
/** The encoded form of the cert path */
private byte[] data;
/**
* Creates a {@code CertPathRep} with the specified
* type and encoded form of a certification path.
*
* @param type the standard name of a {@code CertPath} type
* @param data the encoded form of the certification path
*/
protected CertPathRep(String type, byte[] data) {
this.type = type;
this.data = data;
}
/**
* Returns a {@code CertPath} constructed from the type and data.
*
* @return the resolved {@code CertPath} object
*
* @throws ObjectStreamException if a {@code CertPath} could not
* be constructed
*/
protected Object readResolve() throws ObjectStreamException {
try {
CertificateFactory cf = CertificateFactory.getInstance(type);
return cf.generateCertPath(new ByteArrayInputStream(data));
} catch (CertificateException ce) {
NotSerializableException nse =
new NotSerializableException
("java.security.cert.CertPath: " + type);
nse.initCause(ce);
throw nse;
}
}
}
}

View file

@ -0,0 +1,348 @@
/*
* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security.cert;
import java.security.AccessController;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivilegedAction;
import java.security.Provider;
import java.security.Security;
import java.util.Objects;
import sun.security.jca.*;
import sun.security.jca.GetInstance.Instance;
/**
* A class for building certification paths (also known as certificate chains).
* <p>
* This class uses a provider-based architecture.
* To create a {@code CertPathBuilder}, call
* one of the static {@code getInstance} methods, passing in the
* algorithm name of the {@code CertPathBuilder} desired and optionally
* the name of the provider desired.
*
* <p>Once a {@code CertPathBuilder} object has been created, certification
* paths can be constructed by calling the {@link #build build} method and
* passing it an algorithm-specific set of parameters. If successful, the
* result (including the {@code CertPath} that was built) is returned
* in an object that implements the {@code CertPathBuilderResult}
* interface.
*
* <p>The {@link #getRevocationChecker} method allows an application to specify
* additional algorithm-specific parameters and options used by the
* {@code CertPathBuilder} when checking the revocation status of certificates.
* Here is an example demonstrating how it is used with the PKIX algorithm:
*
* <pre>
* CertPathBuilder cpb = CertPathBuilder.getInstance("PKIX");
* PKIXRevocationChecker rc = (PKIXRevocationChecker)cpb.getRevocationChecker();
* rc.setOptions(EnumSet.of(Option.PREFER_CRLS));
* params.addCertPathChecker(rc);
* CertPathBuilderResult cpbr = cpb.build(params);
* </pre>
*
* <p>Every implementation of the Java platform is required to support the
* following standard {@code CertPathBuilder} algorithm:
* <ul>
* <li>{@code PKIX}</li>
* </ul>
* This algorithm is described in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#certpathbuilder-algorithms">
* CertPathBuilder section</a> of the
* Java Security Standard Algorithm Names Specification.
* Consult the release documentation for your implementation to see if any
* other algorithms are supported.
*
* <p>
* <b>Concurrent Access</b>
* <p>
* The static methods of this class are guaranteed to be thread-safe.
* Multiple threads may concurrently invoke the static methods defined in
* this class with no ill effects.
* <p>
* However, this is not true for the non-static methods defined by this class.
* Unless otherwise documented by a specific provider, threads that need to
* access a single {@code CertPathBuilder} instance concurrently should
* synchronize amongst themselves and provide the necessary locking. Multiple
* threads each manipulating a different {@code CertPathBuilder} instance
* need not synchronize.
*
* @see CertPath
*
* @since 1.4
* @author Sean Mullan
* @author Yassir Elley
*/
public class CertPathBuilder {
/*
* Constant to lookup in the Security properties file to determine
* the default certpathbuilder type. In the Security properties file,
* the default certpathbuilder type is given as:
* <pre>
* certpathbuilder.type=PKIX
* </pre>
*/
private static final String CPB_TYPE = "certpathbuilder.type";
private final CertPathBuilderSpi builderSpi;
private final Provider provider;
private final String algorithm;
/**
* Creates a {@code CertPathBuilder} object of the given algorithm,
* and encapsulates the given provider implementation (SPI object) in it.
*
* @param builderSpi the provider implementation
* @param provider the provider
* @param algorithm the algorithm name
*/
protected CertPathBuilder(CertPathBuilderSpi builderSpi, Provider provider,
String algorithm)
{
this.builderSpi = builderSpi;
this.provider = provider;
this.algorithm = algorithm;
}
/**
* Returns a {@code CertPathBuilder} object that implements the
* specified algorithm.
*
* <p> This method traverses the list of registered security Providers,
* starting with the most preferred Provider.
* A new CertPathBuilder object encapsulating the
* CertPathBuilderSpi implementation from the first
* Provider that supports the specified algorithm is returned.
*
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @implNote
* The JDK Reference Implementation additionally uses the
* {@code jdk.security.provider.preferred}
* {@link Security#getProperty(String) Security} property to determine
* the preferred provider order for the specified algorithm. This
* may be different than the order of providers returned by
* {@link Security#getProviders() Security.getProviders()}.
*
* @param algorithm the name of the requested {@code CertPathBuilder}
* algorithm. See the CertPathBuilder section in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#certpathbuilder-algorithms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard algorithm names.
*
* @return a {@code CertPathBuilder} object that implements the
* specified algorithm
*
* @throws NoSuchAlgorithmException if no {@code Provider} supports a
* {@code CertPathBuilderSpi} implementation for the
* specified algorithm
*
* @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static CertPathBuilder getInstance(String algorithm)
throws NoSuchAlgorithmException {
Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = GetInstance.getInstance("CertPathBuilder",
CertPathBuilderSpi.class, algorithm);
return new CertPathBuilder((CertPathBuilderSpi)instance.impl,
instance.provider, algorithm);
}
/**
* Returns a {@code CertPathBuilder} object that implements the
* specified algorithm.
*
* <p> A new CertPathBuilder object encapsulating the
* CertPathBuilderSpi implementation from the specified provider
* is returned. The specified provider must be registered
* in the security provider list.
*
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param algorithm the name of the requested {@code CertPathBuilder}
* algorithm. See the CertPathBuilder section in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#certpathbuilder-algorithms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard algorithm names.
*
* @param provider the name of the provider.
*
* @return a {@code CertPathBuilder} object that implements the
* specified algorithm
*
* @throws IllegalArgumentException if the {@code provider} is
* {@code null} or empty
*
* @throws NoSuchAlgorithmException if a {@code CertPathBuilderSpi}
* implementation for the specified algorithm is not
* available from the specified provider
*
* @throws NoSuchProviderException if the specified provider is not
* registered in the security provider list
*
* @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static CertPathBuilder getInstance(String algorithm, String provider)
throws NoSuchAlgorithmException, NoSuchProviderException {
Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = GetInstance.getInstance("CertPathBuilder",
CertPathBuilderSpi.class, algorithm, provider);
return new CertPathBuilder((CertPathBuilderSpi)instance.impl,
instance.provider, algorithm);
}
/**
* Returns a {@code CertPathBuilder} object that implements the
* specified algorithm.
*
* <p> A new CertPathBuilder object encapsulating the
* CertPathBuilderSpi implementation from the specified Provider
* object is returned. Note that the specified Provider object
* does not have to be registered in the provider list.
*
* @param algorithm the name of the requested {@code CertPathBuilder}
* algorithm. See the CertPathBuilder section in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#certpathbuilder-algorithms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard algorithm names.
*
* @param provider the provider.
*
* @return a {@code CertPathBuilder} object that implements the
* specified algorithm
*
* @throws IllegalArgumentException if the {@code provider} is
* {@code null}
*
* @throws NoSuchAlgorithmException if a {@code CertPathBuilderSpi}
* implementation for the specified algorithm is not available
* from the specified {@code Provider} object
*
* @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static CertPathBuilder getInstance(String algorithm,
Provider provider) throws NoSuchAlgorithmException {
Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = GetInstance.getInstance("CertPathBuilder",
CertPathBuilderSpi.class, algorithm, provider);
return new CertPathBuilder((CertPathBuilderSpi)instance.impl,
instance.provider, algorithm);
}
/**
* Returns the provider of this {@code CertPathBuilder}.
*
* @return the provider of this {@code CertPathBuilder}
*/
public final Provider getProvider() {
return this.provider;
}
/**
* Returns the name of the algorithm of this {@code CertPathBuilder}.
*
* @return the name of the algorithm of this {@code CertPathBuilder}
*/
public final String getAlgorithm() {
return this.algorithm;
}
/**
* Attempts to build a certification path using the specified algorithm
* parameter set.
*
* @param params the algorithm parameters
* @return the result of the build algorithm
* @throws CertPathBuilderException if the builder is unable to construct
* a certification path that satisfies the specified parameters
* @throws InvalidAlgorithmParameterException if the specified parameters
* are inappropriate for this {@code CertPathBuilder}
*/
public final CertPathBuilderResult build(CertPathParameters params)
throws CertPathBuilderException, InvalidAlgorithmParameterException
{
return builderSpi.engineBuild(params);
}
/**
* Returns the default {@code CertPathBuilder} type as specified by
* the {@code certpathbuilder.type} security property, or the string
* {@literal "PKIX"} if no such property exists.
*
* <p>The default {@code CertPathBuilder} type can be used by
* applications that do not want to use a hard-coded type when calling one
* of the {@code getInstance} methods, and want to provide a default
* type in case a user does not specify its own.
*
* <p>The default {@code CertPathBuilder} type can be changed by
* setting the value of the {@code certpathbuilder.type} security property
* to the desired type.
*
* @see java.security.Security security properties
* @return the default {@code CertPathBuilder} type as specified
* by the {@code certpathbuilder.type} security property, or the string
* {@literal "PKIX"} if no such property exists.
*/
public static final String getDefaultType() {
String cpbtype =
AccessController.doPrivileged(new PrivilegedAction<>() {
public String run() {
return Security.getProperty(CPB_TYPE);
}
});
return (cpbtype == null) ? "PKIX" : cpbtype;
}
/**
* Returns a {@code CertPathChecker} that the encapsulated
* {@code CertPathBuilderSpi} implementation uses to check the revocation
* status of certificates. A PKIX implementation returns objects of
* type {@code PKIXRevocationChecker}. Each invocation of this method
* returns a new instance of {@code CertPathChecker}.
*
* <p>The primary purpose of this method is to allow callers to specify
* additional input parameters and options specific to revocation checking.
* See the class description for an example.
*
* @return a {@code CertPathChecker}
* @throws UnsupportedOperationException if the service provider does not
* support this method
* @since 1.8
*/
public final CertPathChecker getRevocationChecker() {
return builderSpi.engineGetRevocationChecker();
}
}

View file

@ -0,0 +1,104 @@
/*
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security.cert;
import java.security.GeneralSecurityException;
/**
* An exception indicating one of a variety of problems encountered when
* building a certification path with a {@code CertPathBuilder}.
* <p>
* A {@code CertPathBuilderException} provides support for wrapping
* exceptions. The {@link #getCause getCause} method returns the throwable,
* if any, that caused this exception to be thrown.
* <p>
* <b>Concurrent Access</b>
* <p>
* Unless otherwise specified, the methods defined in this class are not
* thread-safe. Multiple threads that need to access a single
* object concurrently should synchronize amongst themselves and
* provide the necessary locking. Multiple threads each manipulating
* separate objects need not synchronize.
*
* @see CertPathBuilder
*
* @since 1.4
* @author Sean Mullan
*/
public class CertPathBuilderException extends GeneralSecurityException {
private static final long serialVersionUID = 5316471420178794402L;
/**
* Creates a {@code CertPathBuilderException} with {@code null}
* as its detail message.
*/
public CertPathBuilderException() {
super();
}
/**
* Creates a {@code CertPathBuilderException} with the given
* detail message. The detail message is a {@code String} that
* describes this particular exception in more detail.
*
* @param msg the detail message
*/
public CertPathBuilderException(String msg) {
super(msg);
}
/**
* Creates a {@code CertPathBuilderException} that wraps the specified
* throwable. This allows any exception to be converted into a
* {@code CertPathBuilderException}, while retaining information
* about the wrapped exception, which may be useful for debugging. The
* detail message is set to ({@code cause==null ? null : cause.toString()})
* (which typically contains the class and detail message of
* cause).
*
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause getCause()} method). (A {@code null} value is
* permitted, and indicates that the cause is nonexistent or unknown.)
*/
public CertPathBuilderException(Throwable cause) {
super(cause);
}
/**
* Creates a {@code CertPathBuilderException} with the specified
* detail message and cause.
*
* @param msg the detail message
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause getCause()} method). (A {@code null} value is
* permitted, and indicates that the cause is nonexistent or unknown.)
*/
public CertPathBuilderException(String msg, Throwable cause) {
super(msg, cause);
}
}

View file

@ -0,0 +1,68 @@
/*
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security.cert;
/**
* A specification of the result of a certification path builder algorithm.
* All results returned by the {@link CertPathBuilder#build
* CertPathBuilder.build} method must implement this interface.
* <p>
* At a minimum, a {@code CertPathBuilderResult} contains the
* {@code CertPath} built by the {@code CertPathBuilder} instance.
* Implementations of this interface may add methods to return implementation
* or algorithm specific information, such as debugging information or
* certification path validation results.
* <p>
* <b>Concurrent Access</b>
* <p>
* Unless otherwise specified, the methods defined in this interface are not
* thread-safe. Multiple threads that need to access a single
* object concurrently should synchronize amongst themselves and
* provide the necessary locking. Multiple threads each manipulating
* separate objects need not synchronize.
*
* @see CertPathBuilder
*
* @since 1.4
* @author Sean Mullan
*/
public interface CertPathBuilderResult extends Cloneable {
/**
* Returns the built certification path.
*
* @return the certification path (never {@code null})
*/
CertPath getCertPath();
/**
* Makes a copy of this {@code CertPathBuilderResult}. Changes to the
* copy will not affect the original and vice versa.
*
* @return a copy of this {@code CertPathBuilderResult}
*/
Object clone();
}

View file

@ -0,0 +1,98 @@
/*
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security.cert;
import java.security.InvalidAlgorithmParameterException;
/**
* The <i>Service Provider Interface</i> (<b>SPI</b>)
* for the {@link CertPathBuilder CertPathBuilder} class. All
* {@code CertPathBuilder} implementations must include a class (the
* SPI class) that extends this class ({@code CertPathBuilderSpi}) and
* implements all of its methods. In general, instances of this class should
* only be accessed through the {@code CertPathBuilder} class. For
* details, see the Java Cryptography Architecture.
* <p>
* <b>Concurrent Access</b>
* <p>
* Instances of this class need not be protected against concurrent
* access from multiple threads. Threads that need to access a single
* {@code CertPathBuilderSpi} instance concurrently should synchronize
* amongst themselves and provide the necessary locking before calling the
* wrapping {@code CertPathBuilder} object.
* <p>
* However, implementations of {@code CertPathBuilderSpi} may still
* encounter concurrency issues, since multiple threads each
* manipulating a different {@code CertPathBuilderSpi} instance need not
* synchronize.
*
* @since 1.4
* @author Sean Mullan
*/
public abstract class CertPathBuilderSpi {
/**
* The default constructor.
*/
public CertPathBuilderSpi() { }
/**
* Attempts to build a certification path using the specified
* algorithm parameter set.
*
* @param params the algorithm parameters
* @return the result of the build algorithm
* @throws CertPathBuilderException if the builder is unable to construct
* a certification path that satisfies the specified parameters
* @throws InvalidAlgorithmParameterException if the specified parameters
* are inappropriate for this {@code CertPathBuilder}
*/
public abstract CertPathBuilderResult engineBuild(CertPathParameters params)
throws CertPathBuilderException, InvalidAlgorithmParameterException;
/**
* Returns a {@code CertPathChecker} that this implementation uses to
* check the revocation status of certificates. A PKIX implementation
* returns objects of type {@code PKIXRevocationChecker}.
*
* <p>The primary purpose of this method is to allow callers to specify
* additional input parameters and options specific to revocation checking.
* See the class description of {@code CertPathBuilder} for an example.
*
* <p>This method was added to version 1.8 of the Java Platform Standard
* Edition. In order to maintain backwards compatibility with existing
* service providers, this method cannot be abstract and by default throws
* an {@code UnsupportedOperationException}.
*
* @return a {@code CertPathChecker} that this implementation uses to
* check the revocation status of certificates
* @throws UnsupportedOperationException if this method is not supported
* @since 1.8
*/
public CertPathChecker engineGetRevocationChecker() {
throw new UnsupportedOperationException();
}
}

View file

@ -0,0 +1,77 @@
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security.cert;
/**
* <p>Performs one or more checks on each {@code Certificate} of a
* {@code CertPath}.
*
* <p>A {@code CertPathChecker} implementation is typically created to extend
* a certification path validation algorithm. For example, an implementation
* may check for and process a critical private extension of each certificate
* in a certification path.
*
* @since 1.8
*/
public interface CertPathChecker {
/**
* Initializes the internal state of this {@code CertPathChecker}.
*
* <p>The {@code forward} flag specifies the order that certificates will
* be passed to the {@link #check check} method (forward or reverse).
*
* @param forward the order that certificates are presented to the
* {@code check} method. If {@code true}, certificates are
* presented from target to trust anchor (forward); if
* {@code false}, from trust anchor to target (reverse).
* @throws CertPathValidatorException if this {@code CertPathChecker} is
* unable to check certificates in the specified order
*/
void init(boolean forward) throws CertPathValidatorException;
/**
* Indicates if forward checking is supported. Forward checking refers
* to the ability of the {@code CertPathChecker} to perform its checks
* when certificates are presented to the {@code check} method in the
* forward direction (from target to trust anchor).
*
* @return {@code true} if forward checking is supported, {@code false}
* otherwise
*/
boolean isForwardCheckingSupported();
/**
* Performs the check(s) on the specified certificate using its internal
* state. The certificates are presented in the order specified by the
* {@code init} method.
*
* @param cert the {@code Certificate} to be checked
* @throws CertPathValidatorException if the specified certificate does
* not pass the check
*/
void check(Certificate cert) throws CertPathValidatorException;
}

View file

@ -0,0 +1,66 @@
/*
* Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security.cert;
import java.util.*;
import sun.security.provider.certpath.CertPathHelper;
import sun.security.x509.GeneralNameInterface;
/**
* Helper class that allows the Sun CertPath provider to access
* implementation dependent APIs in CertPath framework.
*
* @author Andreas Sterbenz
*/
class CertPathHelperImpl extends CertPathHelper {
private CertPathHelperImpl() {
// empty
}
/**
* Initialize the helper framework. This method must be called from
* the static initializer of each class that is the target of one of
* the methods in this class. This ensures that the helper is initialized
* prior to a tunneled call from the Sun provider.
*/
static synchronized void initialize() {
if (CertPathHelper.instance == null) {
CertPathHelper.instance = new CertPathHelperImpl();
}
}
protected void implSetPathToNames(X509CertSelector sel,
Set<GeneralNameInterface> names) {
sel.setPathToNamesInternal(names);
}
protected void implSetDateAndTime(X509CRLSelector sel, Date date, long skew) {
sel.setDateAndTime(date, skew);
}
}

View file

@ -0,0 +1,49 @@
/*
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security.cert;
/**
* A specification of certification path algorithm parameters.
* The purpose of this interface is to group (and provide type safety for)
* all {@code CertPath} parameter specifications. All
* {@code CertPath} parameter specifications must implement this
* interface.
*
* @author Yassir Elley
* @see CertPathValidator#validate(CertPath, CertPathParameters)
* @see CertPathBuilder#build(CertPathParameters)
* @since 1.4
*/
public interface CertPathParameters extends Cloneable {
/**
* Makes a copy of this {@code CertPathParameters}. Changes to the
* copy will not affect the original and vice versa.
*
* @return a copy of this {@code CertPathParameters}
*/
Object clone();
}

View file

@ -0,0 +1,360 @@
/*
* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security.cert;
import java.security.AccessController;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivilegedAction;
import java.security.Provider;
import java.security.Security;
import java.util.Objects;
import sun.security.jca.*;
import sun.security.jca.GetInstance.Instance;
/**
* A class for validating certification paths (also known as certificate
* chains).
* <p>
* This class uses a provider-based architecture.
* To create a {@code CertPathValidator},
* call one of the static {@code getInstance} methods, passing in the
* algorithm name of the {@code CertPathValidator} desired and
* optionally the name of the provider desired.
*
* <p>Once a {@code CertPathValidator} object has been created, it can
* be used to validate certification paths by calling the {@link #validate
* validate} method and passing it the {@code CertPath} to be validated
* and an algorithm-specific set of parameters. If successful, the result is
* returned in an object that implements the
* {@code CertPathValidatorResult} interface.
*
* <p>The {@link #getRevocationChecker} method allows an application to specify
* additional algorithm-specific parameters and options used by the
* {@code CertPathValidator} when checking the revocation status of
* certificates. Here is an example demonstrating how it is used with the PKIX
* algorithm:
*
* <pre>
* CertPathValidator cpv = CertPathValidator.getInstance("PKIX");
* PKIXRevocationChecker rc = (PKIXRevocationChecker)cpv.getRevocationChecker();
* rc.setOptions(EnumSet.of(Option.SOFT_FAIL));
* params.addCertPathChecker(rc);
* CertPathValidatorResult cpvr = cpv.validate(path, params);
* </pre>
*
* <p>Every implementation of the Java platform is required to support the
* following standard {@code CertPathValidator} algorithm:
* <ul>
* <li>{@code PKIX}</li>
* </ul>
* This algorithm is described in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#certpathvalidator-algorithms">
* CertPathValidator section</a> of the
* Java Security Standard Algorithm Names Specification.
* Consult the release documentation for your implementation to see if any
* other algorithms are supported.
*
* <p>
* <b>Concurrent Access</b>
* <p>
* The static methods of this class are guaranteed to be thread-safe.
* Multiple threads may concurrently invoke the static methods defined in
* this class with no ill effects.
* <p>
* However, this is not true for the non-static methods defined by this class.
* Unless otherwise documented by a specific provider, threads that need to
* access a single {@code CertPathValidator} instance concurrently should
* synchronize amongst themselves and provide the necessary locking. Multiple
* threads each manipulating a different {@code CertPathValidator}
* instance need not synchronize.
*
* @see CertPath
*
* @since 1.4
* @author Yassir Elley
*/
public class CertPathValidator {
/*
* Constant to lookup in the Security properties file to determine
* the default certpathvalidator type. In the Security properties file,
* the default certpathvalidator type is given as:
* <pre>
* certpathvalidator.type=PKIX
* </pre>
*/
private static final String CPV_TYPE = "certpathvalidator.type";
private final CertPathValidatorSpi validatorSpi;
private final Provider provider;
private final String algorithm;
/**
* Creates a {@code CertPathValidator} object of the given algorithm,
* and encapsulates the given provider implementation (SPI object) in it.
*
* @param validatorSpi the provider implementation
* @param provider the provider
* @param algorithm the algorithm name
*/
protected CertPathValidator(CertPathValidatorSpi validatorSpi,
Provider provider, String algorithm)
{
this.validatorSpi = validatorSpi;
this.provider = provider;
this.algorithm = algorithm;
}
/**
* Returns a {@code CertPathValidator} object that implements the
* specified algorithm.
*
* <p> This method traverses the list of registered security Providers,
* starting with the most preferred Provider.
* A new CertPathValidator object encapsulating the
* CertPathValidatorSpi implementation from the first
* Provider that supports the specified algorithm is returned.
*
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @implNote
* The JDK Reference Implementation additionally uses the
* {@code jdk.security.provider.preferred}
* {@link Security#getProperty(String) Security} property to determine
* the preferred provider order for the specified algorithm. This
* may be different than the order of providers returned by
* {@link Security#getProviders() Security.getProviders()}.
*
* @param algorithm the name of the requested {@code CertPathValidator}
* algorithm. See the CertPathValidator section in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#certpathvalidator-algorithms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard algorithm names.
*
* @return a {@code CertPathValidator} object that implements the
* specified algorithm
*
* @throws NoSuchAlgorithmException if no {@code Provider} supports a
* {@code CertPathValidatorSpi} implementation for the
* specified algorithm
*
* @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static CertPathValidator getInstance(String algorithm)
throws NoSuchAlgorithmException {
Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = GetInstance.getInstance("CertPathValidator",
CertPathValidatorSpi.class, algorithm);
return new CertPathValidator((CertPathValidatorSpi)instance.impl,
instance.provider, algorithm);
}
/**
* Returns a {@code CertPathValidator} object that implements the
* specified algorithm.
*
* <p> A new CertPathValidator object encapsulating the
* CertPathValidatorSpi implementation from the specified provider
* is returned. The specified provider must be registered
* in the security provider list.
*
* <p> Note that the list of registered providers may be retrieved via
* the {@link Security#getProviders() Security.getProviders()} method.
*
* @param algorithm the name of the requested {@code CertPathValidator}
* algorithm. See the CertPathValidator section in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#certpathvalidator-algorithms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard algorithm names.
*
* @param provider the name of the provider.
*
* @return a {@code CertPathValidator} object that implements the
* specified algorithm
*
* @throws IllegalArgumentException if the {@code provider} is
* {@code null} or empty
*
* @throws NoSuchAlgorithmException if a {@code CertPathValidatorSpi}
* implementation for the specified algorithm is not
* available from the specified provider
*
* @throws NoSuchProviderException if the specified provider is not
* registered in the security provider list
*
* @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static CertPathValidator getInstance(String algorithm,
String provider) throws NoSuchAlgorithmException,
NoSuchProviderException {
Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = GetInstance.getInstance("CertPathValidator",
CertPathValidatorSpi.class, algorithm, provider);
return new CertPathValidator((CertPathValidatorSpi)instance.impl,
instance.provider, algorithm);
}
/**
* Returns a {@code CertPathValidator} object that implements the
* specified algorithm.
*
* <p> A new CertPathValidator object encapsulating the
* CertPathValidatorSpi implementation from the specified Provider
* object is returned. Note that the specified Provider object
* does not have to be registered in the provider list.
*
* @param algorithm the name of the requested {@code CertPathValidator}
* algorithm. See the CertPathValidator section in the <a href=
* "{@docRoot}/../specs/security/standard-names.html#certpathvalidator-algorithms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard algorithm names.
*
* @param provider the provider.
*
* @return a {@code CertPathValidator} object that implements the
* specified algorithm
*
* @throws IllegalArgumentException if the {@code provider} is
* {@code null}
*
* @throws NoSuchAlgorithmException if a {@code CertPathValidatorSpi}
* implementation for the specified algorithm is not available
* from the specified Provider object
*
* @throws NullPointerException if {@code algorithm} is {@code null}
*
* @see java.security.Provider
*/
public static CertPathValidator getInstance(String algorithm,
Provider provider) throws NoSuchAlgorithmException {
Objects.requireNonNull(algorithm, "null algorithm name");
Instance instance = GetInstance.getInstance("CertPathValidator",
CertPathValidatorSpi.class, algorithm, provider);
return new CertPathValidator((CertPathValidatorSpi)instance.impl,
instance.provider, algorithm);
}
/**
* Returns the {@code Provider} of this
* {@code CertPathValidator}.
*
* @return the {@code Provider} of this {@code CertPathValidator}
*/
public final Provider getProvider() {
return this.provider;
}
/**
* Returns the algorithm name of this {@code CertPathValidator}.
*
* @return the algorithm name of this {@code CertPathValidator}
*/
public final String getAlgorithm() {
return this.algorithm;
}
/**
* Validates the specified certification path using the specified
* algorithm parameter set.
* <p>
* The {@code CertPath} specified must be of a type that is
* supported by the validation algorithm, otherwise an
* {@code InvalidAlgorithmParameterException} will be thrown. For
* example, a {@code CertPathValidator} that implements the PKIX
* algorithm validates {@code CertPath} objects of type X.509.
*
* @param certPath the {@code CertPath} to be validated
* @param params the algorithm parameters
* @return the result of the validation algorithm
* @exception CertPathValidatorException if the {@code CertPath}
* does not validate
* @exception InvalidAlgorithmParameterException if the specified
* parameters or the type of the specified {@code CertPath} are
* inappropriate for this {@code CertPathValidator}
*/
public final CertPathValidatorResult validate(CertPath certPath,
CertPathParameters params)
throws CertPathValidatorException, InvalidAlgorithmParameterException
{
return validatorSpi.engineValidate(certPath, params);
}
/**
* Returns the default {@code CertPathValidator} type as specified by
* the {@code certpathvalidator.type} security property, or the string
* {@literal "PKIX"} if no such property exists.
*
* <p>The default {@code CertPathValidator} type can be used by
* applications that do not want to use a hard-coded type when calling one
* of the {@code getInstance} methods, and want to provide a default
* type in case a user does not specify its own.
*
* <p>The default {@code CertPathValidator} type can be changed by
* setting the value of the {@code certpathvalidator.type} security
* property to the desired type.
*
* @see java.security.Security security properties
* @return the default {@code CertPathValidator} type as specified
* by the {@code certpathvalidator.type} security property, or the string
* {@literal "PKIX"} if no such property exists.
*/
public static final String getDefaultType() {
String cpvtype =
AccessController.doPrivileged(new PrivilegedAction<>() {
public String run() {
return Security.getProperty(CPV_TYPE);
}
});
return (cpvtype == null) ? "PKIX" : cpvtype;
}
/**
* Returns a {@code CertPathChecker} that the encapsulated
* {@code CertPathValidatorSpi} implementation uses to check the revocation
* status of certificates. A PKIX implementation returns objects of
* type {@code PKIXRevocationChecker}. Each invocation of this method
* returns a new instance of {@code CertPathChecker}.
*
* <p>The primary purpose of this method is to allow callers to specify
* additional input parameters and options specific to revocation checking.
* See the class description for an example.
*
* @return a {@code CertPathChecker}
* @throws UnsupportedOperationException if the service provider does not
* support this method
* @since 1.8
*/
public final CertPathChecker getRevocationChecker() {
return validatorSpi.engineGetRevocationChecker();
}
}

View file

@ -0,0 +1,296 @@
/*
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.security.cert;
import java.io.InvalidObjectException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.security.GeneralSecurityException;
/**
* An exception indicating one of a variety of problems encountered when
* validating a certification path.
* <p>
* A {@code CertPathValidatorException} provides support for wrapping
* exceptions. The {@link #getCause getCause} method returns the throwable,
* if any, that caused this exception to be thrown.
* <p>
* A {@code CertPathValidatorException} may also include the
* certification path that was being validated when the exception was thrown,
* the index of the certificate in the certification path that caused the
* exception to be thrown, and the reason that caused the failure. Use the
* {@link #getCertPath getCertPath}, {@link #getIndex getIndex}, and
* {@link #getReason getReason} methods to retrieve this information.
*
* <p>
* <b>Concurrent Access</b>
* <p>
* Unless otherwise specified, the methods defined in this class are not
* thread-safe. Multiple threads that need to access a single
* object concurrently should synchronize amongst themselves and
* provide the necessary locking. Multiple threads each manipulating
* separate objects need not synchronize.
*
* @see CertPathValidator
*
* @since 1.4
* @author Yassir Elley
*/
public class CertPathValidatorException extends GeneralSecurityException {
private static final long serialVersionUID = -3083180014971893139L;
/**
* @serial the index of the certificate in the certification path
* that caused the exception to be thrown
*/
private int index = -1;
/**
* @serial the {@code CertPath} that was being validated when
* the exception was thrown
*/
private CertPath certPath;
/**
* @serial the reason the validation failed
*/
private Reason reason = BasicReason.UNSPECIFIED;
/**
* Creates a {@code CertPathValidatorException} with
* no detail message.
*/
public CertPathValidatorException() {
this(null, null);
}
/**
* Creates a {@code CertPathValidatorException} with the given
* detail message. A detail message is a {@code String} that
* describes this particular exception.
*
* @param msg the detail message
*/
public CertPathValidatorException(String msg) {
this(msg, null);
}
/**
* Creates a {@code CertPathValidatorException} that wraps the
* specified throwable. This allows any exception to be converted into a
* {@code CertPathValidatorException}, while retaining information
* about the wrapped exception, which may be useful for debugging. The
* detail message is set to ({@code cause==null ? null : cause.toString()})
* (which typically contains the class and detail message of
* cause).
*
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause getCause()} method). (A {@code null} value is
* permitted, and indicates that the cause is nonexistent or unknown.)
*/
public CertPathValidatorException(Throwable cause) {
this((cause == null ? null : cause.toString()), cause);
}
/**
* Creates a {@code CertPathValidatorException} with the specified
* detail message and cause.
*
* @param msg the detail message
* @param cause the cause (which is saved for later retrieval by the
* {@link #getCause getCause()} method). (A {@code null} value is
* permitted, and indicates that the cause is nonexistent or unknown.)
*/
public CertPathValidatorException(String msg, Throwable cause) {
this(msg, cause, null, -1);
}
/**
* Creates a {@code CertPathValidatorException} with the specified
* detail message, cause, certification path, and index.
*
* @param msg the detail message (or {@code null} if none)
* @param cause the cause (or {@code null} if none)
* @param certPath the certification path that was in the process of
* being validated when the error was encountered
* @param index the index of the certificate in the certification path
* that caused the error (or -1 if not applicable). Note that
* the list of certificates in a {@code CertPath} is zero based.
* @throws IndexOutOfBoundsException if the index is out of range
* {@code (index < -1 || (certPath != null && index >=
* certPath.getCertificates().size()) }
* @throws IllegalArgumentException if {@code certPath} is
* {@code null} and {@code index} is not -1
*/
public CertPathValidatorException(String msg, Throwable cause,
CertPath certPath, int index) {
this(msg, cause, certPath, index, BasicReason.UNSPECIFIED);
}
/**
* Creates a {@code CertPathValidatorException} with the specified
* detail message, cause, certification path, index, and reason.
*
* @param msg the detail message (or {@code null} if none)
* @param cause the cause (or {@code null} if none)
* @param certPath the certification path that was in the process of
* being validated when the error was encountered
* @param index the index of the certificate in the certification path
* that caused the error (or -1 if not applicable). Note that
* the list of certificates in a {@code CertPath} is zero based.
* @param reason the reason the validation failed
* @throws IndexOutOfBoundsException if the index is out of range
* {@code (index < -1 || (certPath != null && index >=
* certPath.getCertificates().size()) }
* @throws IllegalArgumentException if {@code certPath} is
* {@code null} and {@code index} is not -1
* @throws NullPointerException if {@code reason} is {@code null}
*
* @since 1.7
*/
public CertPathValidatorException(String msg, Throwable cause,
CertPath certPath, int index, Reason reason) {
super(msg, cause);
if (certPath == null && index != -1) {
throw new IllegalArgumentException();
}
if (index < -1 ||
(certPath != null && index >= certPath.getCertificates().size())) {
throw new IndexOutOfBoundsException();
}
if (reason == null) {
throw new NullPointerException("reason can't be null");
}
this.certPath = certPath;
this.index = index;
this.reason = reason;
}
/**
* Returns the certification path that was being validated when
* the exception was thrown.
*
* @return the {@code CertPath} that was being validated when
* the exception was thrown (or {@code null} if not specified)
*/
public CertPath getCertPath() {
return this.certPath;
}
/**
* Returns the index of the certificate in the certification path
* that caused the exception to be thrown. Note that the list of
* certificates in a {@code CertPath} is zero based. If no
* index has been set, -1 is returned.
*
* @return the index that has been set, or -1 if none has been set
*/
public int getIndex() {
return this.index;
}
/**
* Returns the reason that the validation failed. The reason is
* associated with the index of the certificate returned by
* {@link #getIndex}.
*
* @return the reason that the validation failed, or
* {@code BasicReason.UNSPECIFIED} if a reason has not been
* specified
*
* @since 1.7
*/
public Reason getReason() {
return this.reason;
}
private void readObject(ObjectInputStream stream)
throws ClassNotFoundException, IOException {
stream.defaultReadObject();
if (reason == null) {
reason = BasicReason.UNSPECIFIED;
}
if (certPath == null && index != -1) {
throw new InvalidObjectException("certpath is null and index != -1");
}
if (index < -1 ||
(certPath != null && index >= certPath.getCertificates().size())) {
throw new InvalidObjectException("index out of range");
}
}
/**
* The reason the validation algorithm failed.
*
* @since 1.7
*/
public static interface Reason extends java.io.Serializable { }
/**
* The BasicReason enumerates the potential reasons that a certification
* path of any type may be invalid.
*
* @since 1.7
*/
public static enum BasicReason implements Reason {
/**
* Unspecified reason.
*/
UNSPECIFIED,
/**
* The certificate is expired.
*/
EXPIRED,
/**
* The certificate is not yet valid.
*/
NOT_YET_VALID,
/**
* The certificate is revoked.
*/
REVOKED,
/**
* The revocation status of the certificate could not be determined.
*/
UNDETERMINED_REVOCATION_STATUS,
/**
* The signature is invalid.
*/
INVALID_SIGNATURE,
/**
* The public key or the signature algorithm has been constrained.
*/
ALGORITHM_CONSTRAINED
}
}

Some files were not shown because too many files have changed in this diff Show more