diff options
Diffstat (limited to 'base/util/src/netscape/security/extensions')
14 files changed, 3053 insertions, 0 deletions
diff --git a/base/util/src/netscape/security/extensions/AccessDescription.java b/base/util/src/netscape/security/extensions/AccessDescription.java new file mode 100644 index 000000000..f13c937e7 --- /dev/null +++ b/base/util/src/netscape/security/extensions/AccessDescription.java @@ -0,0 +1,76 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2007 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package netscape.security.extensions; + +import java.io.IOException; +import java.io.Serializable; + +import netscape.security.util.DerOutputStream; +import netscape.security.util.DerValue; +import netscape.security.util.ObjectIdentifier; +import netscape.security.x509.GeneralName; + +public class AccessDescription implements Serializable { + ObjectIdentifier mOID = null; + GeneralName mLocation = null; + + AccessDescription(ObjectIdentifier oid, GeneralName location) { + mOID = oid; + mLocation = location; + } + + public ObjectIdentifier getMethod() { + return mOID; + } + + public GeneralName getLocation() { + return mLocation; + } + + /** + * For serialization: + * Note that GeneralName is not serializable. That is + * why we need to define our own serialization method. + */ + private void writeObject(java.io.ObjectOutputStream out) + throws IOException { + DerOutputStream seq = new DerOutputStream(); + DerOutputStream tmp = new DerOutputStream(); + + tmp.putOID(mOID); + mLocation.encode(tmp); + seq.write(DerValue.tag_Sequence, tmp); + out.write(seq.toByteArray()); + } + + /** + * For serialization + * Note that GeneralName is not serializable. That is + * why we need to define our own serialization method. + */ + private void readObject(java.io.ObjectInputStream in) + throws IOException { + DerValue val = new DerValue(in); + DerValue seq = val.data.getDerValue(); + + mOID = seq.getOID(); + DerValue derLoc = val.data.getDerValue(); + + mLocation = new GeneralName(derLoc); + } +} diff --git a/base/util/src/netscape/security/extensions/AuthInfoAccessExtension.java b/base/util/src/netscape/security/extensions/AuthInfoAccessExtension.java new file mode 100644 index 000000000..b8e2933dd --- /dev/null +++ b/base/util/src/netscape/security/extensions/AuthInfoAccessExtension.java @@ -0,0 +1,272 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2007 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package netscape.security.extensions; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.security.cert.CertificateException; +import java.util.Enumeration; +import java.util.Vector; + +import com.netscape.cmsutil.util.Utils; + +import netscape.security.util.DerOutputStream; +import netscape.security.util.DerValue; +import netscape.security.util.ObjectIdentifier; +import netscape.security.x509.CertAttrSet; +import netscape.security.x509.Extension; +import netscape.security.x509.GeneralName; +import netscape.security.x509.URIName; + +/** + * This represents the authority information access extension + * as defined in RFC2459. + * + * id-pkix OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) dod(6) + * internet(1) security(5) mechanisms(5) + * pkix(7) } } + * id-pe OBJECT IDENTIFIER ::= { id-pkix 1 } + * id-pe-authorityInfoAccess OBJECT IDENTIFIER ::= { id-pe 1 } + * AuthorityInfoAccessSyntax ::= SEQUENCE SIZE (1..MAX) OF AccessDescription + * AccessDescription ::= SEQUENCE { + * accessMethod OBJECT IDENTIFIER, + * accessLocation GeneralName + * } + * id-ad OBJECT IDENTIFIER ::= { id-pkix 48 } + * id-ad-ocsp OBJECT IDENTIFIER ::= { id-ad 1 } + * id-ad-caIssuers OBJECT IDENTIFIER ::= { id-ad 2 } + * + * Need to make sure the following is added to CMS.cfg: + * oidmap.auth_info_access.class=com.netscape.certsrv.cert.AuthInfoAccessExtension + * oidmap.auth_info_access.oid=1.3.6.1.5.5.7.1.1 + * + * @author thomask + * @version $Revision$, $Date$ + */ +public class AuthInfoAccessExtension extends Extension implements CertAttrSet { + private static final long serialVersionUID = 7373316523212538446L; + public static final String NAME = "AuthInfoAccessExtension"; + public static final String NAME2 = "AuthorityInformationAccess"; + + public static final int OID_OCSP[] = { 1, 3, 6, 1, 5, 5, 7, 48, 1 }; + public static final ObjectIdentifier METHOD_OCSP = new + ObjectIdentifier(OID_OCSP); + + public static final int OID_CA_ISSUERS[] = { 1, 3, 6, 1, 5, 5, 7, 48, 2 }; + public static final ObjectIdentifier METHOD_CA_ISSUERS = new + ObjectIdentifier(OID_CA_ISSUERS); + + public static final int OID[] = { 1, 3, 6, 1, 5, 5, 7, 1, 1 }; + public static final ObjectIdentifier ID = new ObjectIdentifier(OID); + + private Vector<AccessDescription> mDesc = new Vector<AccessDescription>(); + + /** + * Create the extension from the passed DER encoded value of the same. + * + * @param critical true if the extension is to be treated as critical. + * @param value Array of DER encoded bytes of the actual value. + * @exception IOException on error. + */ + public AuthInfoAccessExtension(boolean critical) { + this.extensionId = ID; + this.critical = critical; + this.extensionValue = null; // build this when encodeThis() is called + } + + public AuthInfoAccessExtension(Boolean critical, Object value) + throws IOException { + this.extensionId = ID; + this.critical = critical.booleanValue(); + this.extensionValue = (byte[]) ((byte[]) value).clone(); + decodeThis(); + } + + /** + * Sets extension attribute. + */ + public void set(String name, Object obj) throws CertificateException { + // NOT USED + } + + /** + * Retrieves extension attribute. + */ + public Object get(String name) throws CertificateException { + // NOT USED + return null; + } + + /** + * Deletes attribute. + */ + public void delete(String name) throws CertificateException { + // NOT USED + } + + /** + * Decodes this extension. + */ + public void decode(InputStream in) throws IOException { + // NOT USED + } + + /** + * Return an enumeration of names of attributes existing within this + * attribute. + */ + public Enumeration<String> getAttributeNames() { + // NOT USED + return null; + } + + /** + * Return the name of this attribute. + */ + public String getName() { + return NAME; + } + + /** + * Adds Access Description. + */ + public void addAccessDescription( + ObjectIdentifier method, + GeneralName gn) { + clearValue(); + mDesc.addElement(new AccessDescription(method, gn)); + } + + public AccessDescription getAccessDescription(int pos) { + return mDesc.elementAt(pos); + } + + /** + * Returns the number of access description. + */ + public int numberOfAccessDescription() { + return mDesc.size(); + } + + private void decodeThis() throws IOException { + DerValue val = new DerValue(this.extensionValue); + + if (val.tag != DerValue.tag_Sequence) { + throw new IOException("Invalid encoding of AuthInfoAccess extension"); + } + while (val.data.available() != 0) { + DerValue seq = val.data.getDerValue(); + ObjectIdentifier method = seq.data.getDerValue().getOID(); + GeneralName gn = new GeneralName(seq.data.getDerValue()); + + addAccessDescription(method, gn); + } + } + + private void encodeThis() throws IOException { + DerOutputStream seq = new DerOutputStream(); + DerOutputStream tmp = new DerOutputStream(); + + for (int i = 0; i < mDesc.size(); i++) { + DerOutputStream tmp0 = new DerOutputStream(); + AccessDescription ad = mDesc.elementAt(i); + + tmp0.putOID(ad.getMethod()); + ad.getLocation().encode(tmp0); + tmp.write(DerValue.tag_Sequence, tmp0); + } + seq.write(DerValue.tag_Sequence, tmp); + this.extensionValue = seq.toByteArray(); + } + + /** + * Write the extension to the DerOutputStream. + * + * @param out the DerOutputStream to write the extension to. + * @exception IOException on encoding errors. + */ + public void encode(OutputStream out) throws IOException { + DerOutputStream tmp = new DerOutputStream(); + + if (this.extensionValue == null) { + encodeThis(); + } + super.encode(tmp); + out.write(tmp.toByteArray()); + } + + /** + * Returns a printable representation of the AuthInfoAccess. + */ + public String toString() { + String s = super.toString() + "AuthInfoAccess [\n"; + + for (int i = 0; i < mDesc.size(); i++) { + AccessDescription ad = mDesc.elementAt(i); + + s += "(" + i + ")"; + s += " "; + s += ad.getMethod().toString() + " " + ad.getLocation().toString(); + } + return (s + "]\n"); + } + + public static void main(String[] argv) { + AuthInfoAccessExtension aia = new AuthInfoAccessExtension(false); + GeneralName ocspName = new GeneralName(new + URIName("http://ocsp.netscape.com")); + + aia.addAccessDescription(METHOD_OCSP, ocspName); + GeneralName caIssuersName = new GeneralName(new + URIName("http://ocsp.netscape.com")); + + aia.addAccessDescription(METHOD_CA_ISSUERS, caIssuersName); + ByteArrayOutputStream os = new ByteArrayOutputStream(); + + try { + aia.encode(os); + + System.out.println(Utils.base64encode(os.toByteArray())); + } catch (IOException e) { + System.out.println(e.toString()); + } + + try { + // test serialization + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(bos); + + oos.writeObject(aia); + + ByteArrayInputStream bis = new ByteArrayInputStream( + bos.toByteArray()); + ObjectInputStream ois = new ObjectInputStream(bis); + AuthInfoAccessExtension clone = (AuthInfoAccessExtension) + ois.readObject(); + + System.out.println(clone); + } catch (Exception e) { + System.out.println(e.toString()); + } + } +} diff --git a/base/util/src/netscape/security/extensions/CertInfo.java b/base/util/src/netscape/security/extensions/CertInfo.java new file mode 100644 index 000000000..ab88ec8ab --- /dev/null +++ b/base/util/src/netscape/security/extensions/CertInfo.java @@ -0,0 +1,120 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2007 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package netscape.security.extensions; + +import java.io.IOException; +import java.math.BigInteger; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.util.Date; + +import netscape.security.x509.AlgorithmId; +import netscape.security.x509.CertificateAlgorithmId; +import netscape.security.x509.CertificateIssuerName; +import netscape.security.x509.CertificateSerialNumber; +import netscape.security.x509.CertificateSubjectName; +import netscape.security.x509.CertificateValidity; +import netscape.security.x509.CertificateVersion; +import netscape.security.x509.X500Name; +import netscape.security.x509.X509CertInfo; + +/** + * Extends X509CertInfo class so that minimal fields are initialized at + * creation time so an object of this type is always serializable. + */ +public class CertInfo extends X509CertInfo { + /** + * + */ + private static final long serialVersionUID = -2883888348288591989L; + public static final CertificateSubjectName SERIALIZE_SUBJECT; + public static final CertificateIssuerName SERIALIZE_ISSUER; + public static final CertificateValidity SERIALIZE_VALIDITY; + public static final CertificateSerialNumber SERIALIZE_SERIALNO; + public static final CertificateAlgorithmId SERIALIZE_ALGOR; + public static final CertificateVersion FORCE_VERSION_3; + + static { + try { + // force version 3 + FORCE_VERSION_3 = + new CertificateVersion(CertificateVersion.V3); + SERIALIZE_SUBJECT = + new CertificateSubjectName( + new X500Name("cn=uninitialized")); + SERIALIZE_ISSUER = + new CertificateIssuerName( + new X500Name("cn=uninitialized")); + SERIALIZE_VALIDITY = + new CertificateValidity(new Date(0), new Date(0)); + SERIALIZE_SERIALNO = + new CertificateSerialNumber(new BigInteger("0")); + SERIALIZE_ALGOR = + new CertificateAlgorithmId( + AlgorithmId.getAlgorithmId("MD5withRSA")); + } catch (IOException e) { + // should never happen. If does, system is hosed. + System.out.println("**** Impossible Error encountered ****"); + throw new RuntimeException(e.toString()); + } catch (NoSuchAlgorithmException e) { + // should never happen. If does, system is hosed. + System.out.println("**** Impossible Error encountered ****"); + throw new RuntimeException(e.toString()); + } + } + + /** + * Initializes most fields required by der encoding so object will + * serialize properly. + */ + // XXX should write a class to use something else for serialization + // but this is faster and done now for the time crunch. + public CertInfo() { + super(); + makeSerializable(this); + } + + public static void makeSerializable(X509CertInfo certinfo) { + try { + // force version 3. + certinfo.set(X509CertInfo.VERSION, FORCE_VERSION_3); + + if (certinfo.get(X509CertInfo.SERIAL_NUMBER) == null) { + certinfo.set(X509CertInfo.SERIAL_NUMBER, SERIALIZE_SERIALNO); + } + if (certinfo.get(X509CertInfo.ALGORITHM_ID) == null) { + certinfo.set(X509CertInfo.ALGORITHM_ID, SERIALIZE_ALGOR); + } + if (certinfo.get(X509CertInfo.ISSUER) == null) { + certinfo.set(X509CertInfo.ISSUER, SERIALIZE_ISSUER); + } + if (certinfo.get(X509CertInfo.VALIDITY) == null) { + certinfo.set(X509CertInfo.VALIDITY, SERIALIZE_VALIDITY); + } + // set subject name anyway - it'll get overwritten. + if (certinfo.get(X509CertInfo.SUBJECT) == null) { + certinfo.set(X509CertInfo.SUBJECT, SERIALIZE_SUBJECT); + } + // key is set later in the request. + } // these exceptions shouldn't happen here unless the + // whole process is hosed. + catch (CertificateException e) { + } catch (IOException e) { + } + } +} diff --git a/base/util/src/netscape/security/extensions/CertificateRenewalWindowExtension.java b/base/util/src/netscape/security/extensions/CertificateRenewalWindowExtension.java new file mode 100644 index 000000000..018fd71c8 --- /dev/null +++ b/base/util/src/netscape/security/extensions/CertificateRenewalWindowExtension.java @@ -0,0 +1,190 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2007 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package netscape.security.extensions; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.security.cert.CertificateException; +import java.util.Date; +import java.util.Enumeration; + +import netscape.security.util.DerOutputStream; +import netscape.security.util.DerValue; +import netscape.security.util.ObjectIdentifier; +import netscape.security.x509.CertAttrSet; +import netscape.security.x509.Extension; + +/** + * This represents the CertificateRenewalWindow extension + * as defined in draft-thayes-cert-renewal-00 + * + * CertificateRenewalWindow ::= SEQUENCE { + * beginTime GeneralizedTime, + * endTime GeneralizedTime OPTIONAL } + * + * @author thomask + * @version $Revision$, $Date$ + */ +public class CertificateRenewalWindowExtension extends Extension + implements CertAttrSet { + private static final long serialVersionUID = 4470220533545299271L; + public static final String NAME = "CertificateRenewalWindow"; + public static final int OID[] = { 2, 16, 840, 1, 113730, 1, 15 }; + public static final ObjectIdentifier ID = new ObjectIdentifier(OID); + + private Date mBeginTime = null; + private Date mEndTime = null; // optional + + public CertificateRenewalWindowExtension(boolean critical, Date beginTime, + Date endTime) throws IOException { + this.extensionId = ID; + this.critical = critical; + mBeginTime = beginTime; + mEndTime = endTime; + encodeThis(); + } + + public CertificateRenewalWindowExtension(boolean critical) { + this.extensionId = ID; + this.critical = critical; + this.extensionValue = null; // build this when encodeThis() is called + } + + public CertificateRenewalWindowExtension(Boolean critical, Object value) + throws IOException { + this.extensionId = ID; + this.critical = critical.booleanValue(); + this.extensionValue = (byte[]) ((byte[]) value).clone(); + decodeThis(); + } + + public String getName() { + return NAME; + } + + /** + * Sets extension attribute. + */ + public void set(String name, Object obj) throws CertificateException { + // NOT USED + } + + /** + * Retrieves extension attribute. + */ + public Object get(String name) throws CertificateException { + // NOT USED + return null; + } + + /** + * Deletes attribute. + */ + public void delete(String name) throws CertificateException { + // NOT USED + } + + /** + * Decodes this extension. + */ + public void decode(InputStream in) throws IOException { + // NOT USED + } + + /** + * Return an enumeration of names of attributes existing within this + * attribute. + */ + public Enumeration<String> getAttributeNames() { + // NOT USED + return null; + } + + public Date getBeginTime() { + return mBeginTime; + } + + public Date getEndTime() { + return mEndTime; + } + + public void setBeginTime(Date d) { + mBeginTime = d; + } + + public void setEndTime(Date d) { + mEndTime = d; + } + + private void decodeThis() throws IOException { + DerValue val = new DerValue(this.extensionValue); + + if (val.tag != DerValue.tag_Sequence) { + throw new IOException("Invalid encoding of CertificateWindow extension"); + } + while (val.data.available() != 0) { + if (mBeginTime == null) { + mBeginTime = val.data.getGeneralizedTime(); + } else { + mEndTime = val.data.getGeneralizedTime(); + } + } + } + + private void encodeThis() throws IOException { + DerOutputStream seq = new DerOutputStream(); + DerOutputStream tmp = new DerOutputStream(); + + tmp.putGeneralizedTime(mBeginTime); + if (mEndTime != null) { + tmp.putGeneralizedTime(mEndTime); + } + seq.write(DerValue.tag_Sequence, tmp); + this.extensionValue = seq.toByteArray(); + } + + /** + * Write the extension to the DerOutputStream. + * + * @param out the DerOutputStream to write the extension to. + * @exception IOException on encoding errors. + */ + public void encode(OutputStream out) throws IOException { + DerOutputStream tmp = new DerOutputStream(); + + if (this.extensionValue == null) { + encodeThis(); + } + super.encode(tmp); + out.write(tmp.toByteArray()); + } + + /** + * Returns a printable representation of the CertificateRenewalWindow. + */ + public String toString() { + String s = super.toString() + "CertificateRenewalWindow [\n"; + + s += "BeginTime: " + mBeginTime + "\n"; + if (mEndTime != null) { + s += "EndTime: " + mEndTime; + } + return (s + "]\n"); + } +} diff --git a/base/util/src/netscape/security/extensions/CertificateScopeEntry.java b/base/util/src/netscape/security/extensions/CertificateScopeEntry.java new file mode 100644 index 000000000..527093ccf --- /dev/null +++ b/base/util/src/netscape/security/extensions/CertificateScopeEntry.java @@ -0,0 +1,103 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2007 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package netscape.security.extensions; + +import java.io.IOException; + +import netscape.security.util.BigInt; +import netscape.security.util.DerOutputStream; +import netscape.security.util.DerValue; +import netscape.security.x509.GeneralName; + +/** + * This represents the CertificateScopeOfUse extension + * as defined in draft-thayes-cert-scope-00 + * + * CertificateScopeEntry ::= SEQUENCE { + * name GeneralName, -- pattern, as for NameConstraints + * portNumber INTEGER OPTIONAL + * } + * CertificateScopeOfUse ::= SEQUENCE OF CertificateScopeEntry + * + * @author thomask + * @version $Revision$, $Date$ + */ +public class CertificateScopeEntry { + private GeneralName mGn = null; + private BigInt mPort = null; + + /** + * Constructs scope with der value. + */ + public CertificateScopeEntry(DerValue val) throws IOException { + if (val.tag != DerValue.tag_Sequence) { + throw new IOException("Invalid encoding for PolicyQualifierInfo."); + } + DerValue gn = val.data.getDerValue(); + + mGn = new GeneralName(gn); + if (val.data.available() != 0) { + mPort = val.data.getInteger(); + } + } + + /** + * Constructs scope wit + */ + public CertificateScopeEntry(GeneralName gn, BigInt port) { + mGn = gn; + mPort = port; // optional + } + + public void encode(DerOutputStream out) throws IOException { + DerOutputStream tmp = new DerOutputStream(); + + mGn.encode(tmp); + if (mPort != null) { + tmp.putInteger(mPort); + } + out.write(DerValue.tag_Sequence, tmp); + } + + /** + * Returns a GeneralName + */ + public GeneralName getGeneralName() { + return mGn; + } + + /** + * Returns a port + */ + public BigInt getPort() { + return mPort; + } + + /** + * Returns a printable representation of the CertificateRenewalWindow. + */ + public String toString() { + String s = super.toString() + "CertificateScopeEntry [\n"; + + s += "GeneralName: " + mGn; + if (mPort != null) { + s += "PortNumber: " + mPort; + } + return (s + "]\n"); + } +} diff --git a/base/util/src/netscape/security/extensions/CertificateScopeOfUseExtension.java b/base/util/src/netscape/security/extensions/CertificateScopeOfUseExtension.java new file mode 100644 index 000000000..16641f36b --- /dev/null +++ b/base/util/src/netscape/security/extensions/CertificateScopeOfUseExtension.java @@ -0,0 +1,199 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2007 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package netscape.security.extensions; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.security.cert.CertificateException; +import java.util.Enumeration; +import java.util.Vector; + +import netscape.security.util.DerOutputStream; +import netscape.security.util.DerValue; +import netscape.security.util.ObjectIdentifier; +import netscape.security.x509.CertAttrSet; +import netscape.security.x509.Extension; +import netscape.security.x509.OIDMap; + +/** + * This represents the CertificateScopeOfUse extension + * as defined in draft-thayes-cert-scope-00 + * + * CertificateScopeEntry ::= SEQUENCE { + * name GeneralName, -- pattern, as for NameConstraints + * portNumber INTEGER OPTIONAL + * } + * CertificateScopeOfUse ::= SEQUENCE OF CertificateScopeEntry + * + * @author thomask + * @version $Revision$, $Date$ + */ +public class CertificateScopeOfUseExtension extends Extension + implements CertAttrSet { + /** + * + */ + private static final long serialVersionUID = 2143292831971567770L; + public static final String NAME = "CertificateScopeOfUse"; + public static final int OID[] = { 2, 16, 840, 1, 113730, 1, 17 }; + public static final ObjectIdentifier ID = new ObjectIdentifier(OID); + + private Vector<CertificateScopeEntry> mEntries = null; + + static { + try { + OIDMap.addAttribute(CertificateScopeOfUseExtension.class.getName(), + ID.toString(), NAME); + } catch (CertificateException e) { + } + } + + public CertificateScopeOfUseExtension(boolean critical, Vector<CertificateScopeEntry> scopeEntries) + throws IOException { + this.extensionId = ID; + this.critical = critical; + this.extensionValue = null; // build this when encodeThis() is called + mEntries = scopeEntries; + encodeThis(); + } + + public CertificateScopeOfUseExtension(boolean critical) { + this.extensionId = ID; + this.critical = critical; + this.extensionValue = null; // build this when encodeThis() is called + } + + public CertificateScopeOfUseExtension(Boolean critical, Object value) + throws IOException { + this.extensionId = ID; + this.critical = critical.booleanValue(); + this.extensionValue = (byte[]) ((byte[]) value).clone(); + decodeThis(); + } + + public String getName() { + return NAME; + } + + public Vector<CertificateScopeEntry> getCertificateScopeEntries() { + return mEntries; + } + + /** + * Sets extension attribute. + */ + public void set(String name, Object obj) throws CertificateException { + // NOT USED + } + + /** + * Retrieves extension attribute. + */ + public Object get(String name) throws CertificateException { + // NOT USED + return null; + } + + /** + * Deletes attribute. + */ + public void delete(String name) throws CertificateException { + // NOT USED + } + + /** + * Decodes this extension. + */ + public void decode(InputStream in) throws IOException { + // NOT USED + } + + /** + * Return an enumeration of names of attributes existing within this + * attribute. + */ + public Enumeration<String> getAttributeNames() { + // NOT USED + return null; + } + + private void decodeThis() throws IOException { + DerValue val = new DerValue(this.extensionValue); + + if (val.tag != DerValue.tag_Sequence) { + throw new IOException("Invalid encoding of CertificateWindow extension"); + } + mEntries = new Vector<CertificateScopeEntry>(); + while (val.data.available() != 0) { + mEntries.addElement(new CertificateScopeEntry( + val.data.getDerValue())); + } + } + + private void encodeThis() throws IOException { + DerOutputStream seq = new DerOutputStream(); + DerOutputStream tmp = new DerOutputStream(); + + if (mEntries == null) + throw new IOException("Invalid Scope Entries"); + + for (int i = 0; i < mEntries.size(); i++) { + CertificateScopeEntry se = (CertificateScopeEntry) + mEntries.elementAt(i); + + se.encode(tmp); + } + + seq.write(DerValue.tag_Sequence, tmp); + this.extensionValue = seq.toByteArray(); + } + + /** + * Write the extension to the DerOutputStream. + * + * @param out the DerOutputStream to write the extension to. + * @exception IOException on encoding errors. + */ + public void encode(OutputStream out) throws IOException { + DerOutputStream tmp = new DerOutputStream(); + + if (this.extensionValue == null) { + encodeThis(); + } + super.encode(tmp); + out.write(tmp.toByteArray()); + } + + /** + * Returns a printable representation of the CertificateRenewalWindow. + */ + public String toString() { + String s = super.toString() + "CertificateUseOfScope [\n"; + + if (mEntries != null) { + for (int i = 0; i < mEntries.size(); i++) { + CertificateScopeEntry se = (CertificateScopeEntry) + mEntries.elementAt(i); + + s += se.toString(); + } + } + return (s + "]\n"); + } +} diff --git a/base/util/src/netscape/security/extensions/ExtendedKeyUsageExtension.java b/base/util/src/netscape/security/extensions/ExtendedKeyUsageExtension.java new file mode 100644 index 000000000..939da036f --- /dev/null +++ b/base/util/src/netscape/security/extensions/ExtendedKeyUsageExtension.java @@ -0,0 +1,226 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2007 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package netscape.security.extensions; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.security.cert.CertificateException; +import java.util.Enumeration; +import java.util.Vector; + +import netscape.security.util.DerOutputStream; +import netscape.security.util.DerValue; +import netscape.security.util.ObjectIdentifier; +import netscape.security.x509.CertAttrSet; +import netscape.security.x509.Extension; +import netscape.security.x509.OIDMap; + +/** + * This represents the extended key usage extension. + */ +public class ExtendedKeyUsageExtension extends Extension implements CertAttrSet { + + /** + * + */ + private static final long serialVersionUID = 765403075764697489L; + public static final String OID = "2.5.29.37"; + public static final String NAME = OIDMap.EXT_KEY_USAGE_NAME; + public static final String OID_OCSPSigning = "1.3.6.1.5.5.7.3.9"; + public static final String OID_CODESigning = "1.3.6.1.5.5.7.3.3"; + + public static final int OID_OCSP_SIGNING_STR[] = + { 1, 3, 6, 1, 5, 5, 7, 3, 9 }; + public static final ObjectIdentifier OID_OCSP_SIGNING = new + ObjectIdentifier(OID_OCSP_SIGNING_STR); + + public static final int OID_CODE_SIGNING_STR[] = + { 1, 3, 6, 1, 5, 5, 7, 3, 3 }; + public static final ObjectIdentifier OID_CODE_SIGNING = new + ObjectIdentifier(OID_OCSP_SIGNING_STR); + + private Vector<ObjectIdentifier> oidSet = null; + private byte mCached[] = null; + + static { + try { + OIDMap.addAttribute(ExtendedKeyUsageExtension.class.getName(), + OID, ExtendedKeyUsageExtension.NAME); + } catch (CertificateException e) { + } + } + + public ExtendedKeyUsageExtension() { + this(false, null); + } + + public ExtendedKeyUsageExtension(boolean crit, Vector<ObjectIdentifier> oids) { + try { + extensionId = ObjectIdentifier.getObjectIdentifier(OID); + } catch (IOException e) { + // never here + } + critical = crit; + if (oids != null) { + oidSet = new Vector<ObjectIdentifier>(oids); + } else { + oidSet = new Vector<ObjectIdentifier>(); + } + encodeExtValue(); + } + + public ExtendedKeyUsageExtension(Boolean crit, Object byteVal) + throws IOException { + extensionId = ObjectIdentifier.getObjectIdentifier(OID); + critical = crit.booleanValue(); + extensionValue = (byte[]) ((byte[]) byteVal).clone(); + decodeThis(); + } + + public void setCritical(boolean newValue) { + if (critical != newValue) { + critical = newValue; + mCached = null; + } + } + + public Enumeration<ObjectIdentifier> getOIDs() { + if (oidSet == null) + return null; + return oidSet.elements(); + } + + public void deleteAllOIDs() { + if (oidSet == null) + return; + oidSet.clear(); + } + + public void addOID(ObjectIdentifier oid) { + if (oidSet == null) { + oidSet = new Vector<ObjectIdentifier>(); + } + + if (oidSet.contains(oid)) + return; + oidSet.addElement(oid); + mCached = null; + } + + public void encode(DerOutputStream out) throws IOException { + if (mCached == null) { + encodeExtValue(); + super.encode(out); + mCached = out.toByteArray(); + } + } + + public String toString() { + String presentation = "oid=" + ExtendedKeyUsageExtension.OID + " "; + + if (critical) { + presentation += "critical=true"; + } + if (extensionValue != null) { + String extByteValue = new String(" val="); + + for (int i = 0; i < extensionValue.length; i++) { + extByteValue += (extensionValue[i] + " "); + } + presentation += extByteValue; + } + return presentation; + } + + public void decode(InputStream in) + throws CertificateException, IOException { + } + + public void encode(OutputStream out) + throws CertificateException, IOException { + if (mCached == null) { + DerOutputStream temp = new DerOutputStream(); + + encode(temp); + } + out.write(mCached); + } + + public void set(String name, Object obj) + throws CertificateException, IOException { + // NOT USED + } + + public Object get(String name) throws CertificateException, IOException { + // NOT USED + return null; + } + + public Enumeration<String> getAttributeNames() { + return null; + } + + public String getName() { + return NAME; + } + + public void delete(String name) + throws CertificateException, IOException { + // NOT USED + } + + private void decodeThis() throws IOException { + DerValue val = new DerValue(this.extensionValue); + + if (val.tag != DerValue.tag_Sequence) { + throw new IOException("Invalid encoding of AuthInfoAccess extension"); + } + if (oidSet == null) + oidSet = new Vector<ObjectIdentifier>(); + while (val.data.available() != 0) { + DerValue oidVal = val.data.getDerValue(); + + oidSet.addElement(oidVal.getOID()); + } + } + + private void encodeExtValue() { + DerOutputStream out = new DerOutputStream(); + DerOutputStream temp = new DerOutputStream(); + + if (!oidSet.isEmpty()) { + Enumeration<ObjectIdentifier> oidList = oidSet.elements(); + + try { + while (oidList.hasMoreElements()) { + temp.putOID((ObjectIdentifier) oidList.nextElement()); + } + } catch (IOException ex) { + ex.printStackTrace(); + } + } + + try { + out.write(DerValue.tag_Sequence, temp); + } catch (IOException ex) { + } + + extensionValue = out.toByteArray(); + } +} diff --git a/base/util/src/netscape/security/extensions/GenericASN1Extension.java b/base/util/src/netscape/security/extensions/GenericASN1Extension.java new file mode 100644 index 000000000..ff1ea7173 --- /dev/null +++ b/base/util/src/netscape/security/extensions/GenericASN1Extension.java @@ -0,0 +1,448 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2007 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package netscape.security.extensions; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.lang.reflect.Array; +import java.security.cert.CertificateException; +import java.text.DateFormat; +import java.text.ParseException; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.StringTokenizer; +import java.util.Vector; + +import netscape.security.util.BigInt; +import netscape.security.util.DerOutputStream; +import netscape.security.util.DerValue; +import netscape.security.util.ObjectIdentifier; +import netscape.security.x509.CertAttrSet; +import netscape.security.x509.Extension; +import netscape.security.x509.OIDMap; + +/** + * Represent the AsnInteger Extension. + */ +public class GenericASN1Extension extends Extension + implements CertAttrSet { + /** + * + */ + private static final long serialVersionUID = 8047548816784949009L; + + protected static final int MAX_ATTR = 10; + + protected static final String PROP_CRITICAL = + "critical"; + protected static final String PROP_NAME = + "name"; + protected static final String PROP_OID = + "oid"; + protected static final String PROP_PATTERN = + "pattern"; + protected static final String PROP_ATTRIBUTE = + "attribute"; + protected static final String PROP_TYPE = + "type"; + protected static final String PROP_SOURCE = + "source"; + protected static final String PROP_VALUE = + "value"; + protected static final String PROP_PREDICATE = + "predicate"; + /** + * Identifier for this attribute, to be used with the + * get, set, delete methods of Certificate, x509 type. + */ + private String name; + public String OID = null; + public static Hashtable<String, String> mConfig = null; + public String pattern = null; + private int index = 0; + + // Encode this value + private void encodeThis() + throws IOException, ParseException { + this.extensionValue = encodePattern(); + } + + // Encode pattern + private byte[] encodePattern() + throws IOException, ParseException { + DerOutputStream os = new DerOutputStream(); + DerOutputStream tmp = new DerOutputStream(); + String type = null; + String value = null; + String source = null; + while (index < pattern.length()) { + char ch = pattern.charAt(index); + switch (ch) { + case '{': + index++; + byte[] buff = encodePattern(); + tmp.putDerValue(new DerValue(buff)); + break; + case '}': + os.write(DerValue.tag_Sequence, tmp); + return os.toByteArray(); + default: + type = (String) mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_TYPE); + if (type.equalsIgnoreCase("integer")) { + int num = Integer.parseInt((String) mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_VALUE)); + PutInteger(tmp, num); + } else if (type.equalsIgnoreCase("ia5string")) { + source = (String) mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_SOURCE); + value = (String) mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_VALUE); + if (source.equalsIgnoreCase("file")) + PutIA5String(tmp, getFromFile(value)); + else + PutIA5String(tmp, value); + } else if (type.equalsIgnoreCase("octetstring")) { + source = (String) mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_SOURCE); + value = (String) mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_VALUE); + // It should be colon seperated ASCII Hexdecimal String + if (source.equalsIgnoreCase("file")) + PutOctetString(tmp, getFromFile(value)); + else + PutOctetString(tmp, value); + } else if (type.equalsIgnoreCase("bmpstring")) { + source = (String) mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_SOURCE); + value = (String) mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_VALUE); + if (source.equalsIgnoreCase("file")) + PutBMPString(tmp, getFromFile(value)); + else + PutBMPString(tmp, value); + } else if (type.equalsIgnoreCase("printablestring")) { + source = (String) mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_SOURCE); + value = (String) mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_VALUE); + if (source.equalsIgnoreCase("file")) + PutPrintableString(tmp, getFromFile(value)); + else + PutPrintableString(tmp, value); + } else if (type.equalsIgnoreCase("visiblestring")) { + source = (String) mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_SOURCE); + value = (String) mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_VALUE); + if (source.equalsIgnoreCase("file")) + PutVisibleString(tmp, getFromFile(value)); + else + PutVisibleString(tmp, value); + } else if (type.equalsIgnoreCase("utctime")) { + value = (String) mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_VALUE); + PutUTCtime(tmp, value); + } else if (type.equalsIgnoreCase("oid")) { + value = (String) mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_VALUE); + PutOID(tmp, value); + } else if (type.equalsIgnoreCase("boolean")) { + boolean bool = false; + String b = (String) mConfig.get(PROP_ATTRIBUTE + "." + ch + "." + PROP_VALUE); + if (b.equalsIgnoreCase("true")) + bool = true; + else + bool = false; + PutBoolean(tmp, bool); + } else if (type.equalsIgnoreCase("null")) { + tmp.putNull(); + } else { + throw new ParseException("Unknown Attribute Type", 0); + } + } + index++; + } + + return tmp.toByteArray(); + } + + /** + * Create a GenericASN1Extension with the value and oid. + * The criticality is set to false. + * + * @param the values to be set for the extension. + */ + public GenericASN1Extension(String name, String oid, String pattern, boolean critical, + Hashtable<String, String> config) + throws IOException, ParseException { + ObjectIdentifier tmpid = new ObjectIdentifier(oid); + this.name = name; + OID = oid; + mConfig = config; + this.pattern = pattern; + + try { + if (OIDMap.getName(tmpid) == null) + OIDMap.addAttribute("netscape.security.x509.GenericASN1Extension", oid, name); + } catch (CertificateException e) { + } + + this.extensionId = tmpid; + this.critical = critical; + encodeThis(); + } + + /** + * Create a GenericASN1Extension with the value and oid. + * The criticality is set to false. + * + * @param the values to be set for the extension. + */ + public GenericASN1Extension(Hashtable<String, String> config) + throws IOException, ParseException { + mConfig = config; + ObjectIdentifier tmpid = new ObjectIdentifier((String) mConfig.get(PROP_OID)); + name = (String) mConfig.get(PROP_NAME); + OID = (String) mConfig.get(PROP_OID); + pattern = (String) mConfig.get(PROP_PATTERN); + + try { + if (OIDMap.getName(tmpid) == null) + OIDMap.addAttribute("GenericASN1Extension", OID, name); + } catch (CertificateException e) { + } + + this.extensionId = tmpid; + this.critical = false; + String b = (String) mConfig.get(PROP_CRITICAL); + if (b.equalsIgnoreCase("true")) + this.critical = true; + else + this.critical = false; + encodeThis(); + } + + /** + * Create the extension from the passed DER encoded value of the same. + * + * @param critical true if the extension is to be treated as critical. + * @param value Array of DER encoded bytes of the actual value. + * @exception IOException on error. + */ + public GenericASN1Extension(Boolean critical, Object value) + throws IOException { + this.extensionId = new ObjectIdentifier(OID); + this.critical = critical.booleanValue(); + + int len = Array.getLength(value); + byte[] extValue = new byte[len]; + for (int i = 0; i < len; i++) { + extValue[i] = Array.getByte(value, i); + } + this.extensionValue = extValue; + } + + /** + * Set the attribute value. + */ + public void set(String name, Object obj) throws IOException { + throw new IOException("Method not to be called directly."); + } + + /** + * Get the attribute value. + */ + public Object get(String name) throws IOException { + return null; + } + + /** + * Delete the attribute value. + */ + public void delete(String name) throws IOException { + throw new IOException("Method not to be called directly."); + } + + /** + * Returns a printable representation of the GenericASN1Extension. + */ + public String toString() { + return (null); + } + + /** + * Decode the extension from the InputStream. + * + * @param in the InputStream to unmarshal the contents from. + * @exception IOException on decoding or validity errors. + */ + public void decode(InputStream in) throws IOException { + throw new IOException("Method not to be called directly."); + } + + /** + * Write the extension to the DerOutputStream. + * + * @param out the DerOutputStream to write the extension to. + * @exception IOException on encoding errors. + */ + public void encode(OutputStream out) + throws IOException { + DerOutputStream tmp = new DerOutputStream(); + + try { + if (this.extensionValue == null) { + this.extensionId = new ObjectIdentifier(OID); + this.critical = true; + encodeThis(); + } + } catch (ParseException e) { + } + + super.encode(tmp); + out.write(tmp.toByteArray()); + } + + /** + * Return the name of this attribute. + */ + public String getName() { + return name; + } + + /** + * Set the name of this attribute. + */ + public void setName(String name) { + this.name = name; + } + + /** + * Return the OID of this attribute. + */ + public String getOID() { + return OID; + } + + /** + * Set the OID of this attribute. + */ + public void setOID(String oid) { + OID = oid; + } + + /** + * Return an enumeration of names of attributes existing within this + * attribute. + */ + public Enumeration<String> getAttributeNames() { + Vector<String> elements = new Vector<String>(); + elements.addElement("octet"); + + return (elements.elements()); + } + + private void PutInteger(DerOutputStream os, int number) + throws IOException, ParseException { + os.putInteger(new BigInt(number)); + return; + } + + private void PutIA5String(DerOutputStream os, String value) + throws IOException, ParseException { + os.putIA5String(value); + return; + } + + private void PutOctetString(DerOutputStream os, String value) + throws IOException, ParseException { + StringTokenizer token = new StringTokenizer(value, ":"); + byte[] octets = new byte[token.countTokens()]; + for (int i = 0; token.hasMoreElements(); i++) { + String num = (String) token.nextElement(); + octets[i] = (byte) Integer.parseInt(num, 16); + } + + os.putOctetString(octets); + return; + } + + private void PutBMPString(DerOutputStream os, String value) + throws IOException, ParseException { + os.putBMPString(value); + return; + } + + private void PutPrintableString(DerOutputStream os, String value) + throws IOException, ParseException { + os.putPrintableString(value); + return; + } + + private void PutVisibleString(DerOutputStream os, String value) + throws IOException, ParseException { + os.putVisibleString(value); + return; + } + + private void PutUTCtime(DerOutputStream os, String value) + throws IOException, ParseException { + DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT); + os.putUTCTime(df.parse(value)); + return; + } + + private void PutOID(DerOutputStream os, String value) + throws IOException, ParseException { + os.putOID(new ObjectIdentifier(value)); + return; + } + + private void PutBoolean(DerOutputStream os, boolean value) + throws IOException, ParseException { + os.putBoolean(value); + return; + } + + private String getFromFile(String fname) throws IOException { + String s = null; + byte[] buff = null; + int i = 0; + int j = 0; + if ((fname == null) || (fname.equals(""))) { + throw new IOException("File name is not provided."); + } + + FileInputStream fis = new FileInputStream(fname); + int n = 0; + while ((n = fis.available()) > 0) { + buff = new byte[n]; + int result = fis.read(buff); + if (result == -1) + break; + s = new String(buff); + } + + for (i = 0, j = 0; j < s.length(); j++) { + int ch = (int) s.charAt(j); + if (ch == 10 || ch == 13 || ch == 9) + continue; + i++; + } + buff = new byte[i]; + for (i = 0, j = 0; j < s.length(); j++) { + int ch = (int) s.charAt(j); + if (ch == 10 || ch == 13 || ch == 9) + continue; + buff[i++] = (byte) ch; + } + + s = new String(buff); + + return s; + } +} diff --git a/base/util/src/netscape/security/extensions/InhibitAnyPolicyExtension.java b/base/util/src/netscape/security/extensions/InhibitAnyPolicyExtension.java new file mode 100644 index 000000000..81b8cf5b5 --- /dev/null +++ b/base/util/src/netscape/security/extensions/InhibitAnyPolicyExtension.java @@ -0,0 +1,179 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2007 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package netscape.security.extensions; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.lang.reflect.Array; +import java.security.cert.CertificateException; +import java.util.Enumeration; + +import netscape.security.util.BigInt; +import netscape.security.util.DerOutputStream; +import netscape.security.util.DerValue; +import netscape.security.util.ObjectIdentifier; +import netscape.security.x509.CertAttrSet; +import netscape.security.x509.Extension; +import netscape.security.x509.OIDMap; + +/** + * RFC3280: + * + * id-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::= { id-ce 54 } + * + * InhibitAnyPolicy ::= SkipCerts + * + * SkipCerts ::= INTEGER (0..MAX) + */ +public class InhibitAnyPolicyExtension + extends Extension implements CertAttrSet { + + /** + * + */ + private static final long serialVersionUID = -8963439897419343166L; + public static final String OID = "2.5.29.54"; + public static final String NAME = OIDMap.EXT_INHIBIT_ANY_POLICY_NAME; + + private BigInt mSkipCerts = new BigInt(-1); + + static { + try { + OIDMap.addAttribute(InhibitAnyPolicyExtension.class.getName(), + OID, NAME); + } catch (CertificateException e) { + } + } + + public InhibitAnyPolicyExtension() { + this(false, null); + } + + public InhibitAnyPolicyExtension(boolean crit, BigInt skipCerts) { + try { + extensionId = ObjectIdentifier.getObjectIdentifier(OID); + } catch (IOException e) { + // never here + } + critical = crit; + mSkipCerts = skipCerts; + encodeExtValue(); + } + + public InhibitAnyPolicyExtension(Boolean crit, Object value) + throws IOException { + extensionId = ObjectIdentifier.getObjectIdentifier(OID); + critical = crit.booleanValue(); + //extensionValue = (byte[]) ((byte[]) byteVal).clone(); + int len = Array.getLength(value); + byte[] extValue = new byte[len]; + for (int i = 0; i < len; i++) { + extValue[i] = Array.getByte(value, i); + } + + extensionValue = extValue; + decodeThis(); + } + + public void setCritical(boolean newValue) { + if (critical != newValue) { + critical = newValue; + } + } + + public BigInt getSkipCerts() { + return mSkipCerts; + } + + public String toString() { + String presentation = "ObjectId: " + OID + " "; + + if (critical) { + presentation += "Criticality=true"; + } else { + presentation += "Criticality=false"; + } + if (extensionValue != null) { + String extByteValue = new String(" skipCerts=" + mSkipCerts); + + presentation += extByteValue; + } + return presentation; + } + + public void decode(InputStream in) + throws CertificateException, IOException { + } + + public void set(String name, Object obj) + throws CertificateException, IOException { + // NOT USED + } + + public Object get(String name) throws CertificateException, IOException { + // NOT USED + return null; + } + + public Enumeration<String> getAttributeNames() { + return null; + } + + public String getName() { + return NAME; + } + + public void delete(String name) + throws CertificateException, IOException { + // NOT USED + } + + private void decodeThis() throws IOException { + DerValue val = new DerValue(this.extensionValue); + + mSkipCerts = val.getInteger(); + } + + public void encode(OutputStream out) throws IOException { + DerOutputStream tmp = new DerOutputStream(); + + if (this.extensionValue == null) { + try { + extensionId = ObjectIdentifier.getObjectIdentifier(OID); + } catch (IOException e) { + // never here + } + DerOutputStream os = new DerOutputStream(); + os.putInteger(mSkipCerts); + this.extensionValue = os.toByteArray(); + } + + super.encode(tmp); + out.write(tmp.toByteArray()); + } + + private void encodeExtValue() { + DerOutputStream out = new DerOutputStream(); + try { + out.putInteger(mSkipCerts); + } catch (IOException e) { + } + extensionValue = out.toByteArray(); + } +} diff --git a/base/util/src/netscape/security/extensions/KerberosName.java b/base/util/src/netscape/security/extensions/KerberosName.java new file mode 100644 index 000000000..0a6a6e213 --- /dev/null +++ b/base/util/src/netscape/security/extensions/KerberosName.java @@ -0,0 +1,135 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2007 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package netscape.security.extensions; + +import java.io.ByteArrayOutputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Vector; + +import netscape.security.util.BigInt; +import netscape.security.util.DerOutputStream; +import netscape.security.util.DerValue; +import netscape.security.util.ObjectIdentifier; + +/** + * This represents a KerberosName as defined in + * RFC 1510. + * + * KerberosName ::= SEQUENCE { + * realm [0] Realm, + * principalName [1] CertPrincipalName -- defined above + * } + * + * CertPrincipalName ::= SEQUENCE { + * name-type[0] INTEGER, + * name-string[1] SEQUENCE OF UTF8String + * } + * + * @author thomask + * @version $Revision$, $Date$ + */ +public class KerberosName { + + public static final int OID[] = { 1, 3, 6, 1, 5, 2, 2 }; + public static final ObjectIdentifier KRB5_PRINCIPAL_NAME = new + ObjectIdentifier(OID); + + private String m_realm = null; + private int m_name_type = 0; + private Vector<String> m_name_strings = null; + + public KerberosName(String realm, int name_type, Vector<String> name_strings) { + m_realm = realm; + m_name_type = name_type; + m_name_strings = name_strings; + } + + /** + * Write the extension to the DerOutputStream. + * + * @param out the DerOutputStream to write the extension to. + * @exception IOException on encoding errors. + */ + public void encode(OutputStream out) throws IOException { + + DerOutputStream seq = new DerOutputStream(); + DerOutputStream tmp = new DerOutputStream(); + DerOutputStream realm = new DerOutputStream(); + realm.putGeneralString(m_realm); + tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0), realm); + + DerOutputStream seq1 = new DerOutputStream(); + DerOutputStream tmp1 = new DerOutputStream(); + DerOutputStream name_type = new DerOutputStream(); + name_type.putInteger(new BigInt(m_name_type)); + tmp1.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 0), name_type); + + DerOutputStream name_strings = new DerOutputStream(); + DerOutputStream name_string = new DerOutputStream(); + for (int i = 0; i < m_name_strings.size(); i++) { + name_string.putGeneralString((String) m_name_strings.elementAt(i)); + } + name_strings.write(DerValue.tag_SequenceOf, name_string); + tmp1.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 1), name_strings); + seq1.write(DerValue.tag_Sequence, tmp1); + tmp.write(DerValue.createTag(DerValue.TAG_CONTEXT, + true, (byte) 1), seq1); + + seq.write(DerValue.tag_Sequence, tmp); + out.write(seq.toByteArray()); + } + + public byte[] toByteArray() throws IOException { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + encode(bos); + return bos.toByteArray(); + } + + public String toString() { + String strings = null; + for (int i = 0; i < m_name_strings.size(); i++) { + if (strings == null) { + strings = (String) m_name_strings.elementAt(i); + } else { + strings += ","; + strings += (String) m_name_strings.elementAt(i); + } + } + return "Realm: " + m_realm + " Name Type: " + m_name_type + " Name String(s):" + strings; + } + + public static void main(String[] argv) { + Vector<String> strings = new Vector<String>(); + strings.addElement("name"); + KerberosName k = new KerberosName("realm", 0, strings); + + System.out.println(k.toString()); + try { + FileOutputStream os = new FileOutputStream("/tmp/out.der"); + k.encode(os); + os.close(); + } catch (Exception e) { + System.out.println(e.toString()); + } + } +} diff --git a/base/util/src/netscape/security/extensions/NSCertTypeExtension.java b/base/util/src/netscape/security/extensions/NSCertTypeExtension.java new file mode 100644 index 000000000..04b3038e5 --- /dev/null +++ b/base/util/src/netscape/security/extensions/NSCertTypeExtension.java @@ -0,0 +1,377 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2007 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package netscape.security.extensions; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.security.cert.CertificateException; +import java.util.Enumeration; +import java.util.Vector; + +import netscape.security.util.DerOutputStream; +import netscape.security.util.DerValue; +import netscape.security.util.ObjectIdentifier; +import netscape.security.x509.CertAttrSet; +import netscape.security.x509.Extension; + +/** + * NSCertTypeExtension + * Represents Netscape Certificate Type Extension + * + * <p> + * This deprecated extension, if present, defines both the purpose (e.g., encipherment, signature, certificate signing) + * and the application (e.g., SSL, S/Mime or Object Signing of the key contained in the certificate. + * + * @author galperin + * @version $Revision$, $Date$ + */ +public class NSCertTypeExtension extends Extension implements CertAttrSet { + + /** + * + */ + private static final long serialVersionUID = 1856407688086284397L; + + // The object identifiers + private static final int CertType_data[] = { 2, 16, 840, 1, 113730, 1, 1 }; + + /** + * Identifies the particular public key used to sign the certificate. + */ + public static final ObjectIdentifier CertType_Id = new + ObjectIdentifier(CertType_data); + + /** + * Attribute names. + */ + public static final String NAME = "NSCertType"; + public static final String SSL_CLIENT = "ssl_client"; + public static final String SSL_SERVER = "ssl_server"; + public static final String EMAIL = "email"; + public static final String OBJECT_SIGNING = "object_signing"; + public static final String SSL_CA = "ssl_ca"; + public static final String EMAIL_CA = "email_ca"; + public static final String OBJECT_SIGNING_CA = "object_signing_ca"; + + /** + * Attribute names. + */ + public static final int SSL_CLIENT_BIT = 0; + public static final int SSL_SERVER_BIT = 1; + public static final int EMAIL_BIT = 2; + public static final int OBJECT_SIGNING_BIT = 3; + // 4 is reserved. + public static final int SSL_CA_BIT = 5; + public static final int EMAIL_CA_BIT = 6; + public static final int OBJECT_SIGNING_CA_BIT = 7; + + public static final int NBITS = 8; + + /** + * Identifier for this attribute, to be used with the + * get, set, delete methods of Certificate, x509 type. + */ + public static final String IDENT = "x509.info.extensions.NSCertType"; + + // Private data members + private byte[] mBitString; + + private static class MapEntry { + String mName; + int mPosition; + + MapEntry(String name, int position) { + mName = name; + mPosition = position; + } + } + + private static MapEntry[] mMapData = + { + new MapEntry(SSL_CLIENT, 0), + new MapEntry(SSL_SERVER, 1), + new MapEntry(EMAIL, 2), + new MapEntry(OBJECT_SIGNING, 3), + // note that bit 4 is reserved + new MapEntry(SSL_CA, 5), + new MapEntry(EMAIL_CA, 6), + new MapEntry(OBJECT_SIGNING_CA, 7), + }; + + private static Vector<String> mAttributeNames = new Vector<String>(); + + static { + for (int i = 0; i < mMapData.length; ++i) { + mAttributeNames.addElement(mMapData[i].mName); + } + } + + private static int getPosition(String name) throws CertificateException { + for (int i = 0; i < mMapData.length; ++i) { + if (name.equalsIgnoreCase(mMapData[i].mName)) + return mMapData[i].mPosition; + } + throw new CertificateException("Attribute name [" + name + + "] not recognized by" + + " CertAttrSet:NSCertType."); + } + + // Encode this extension value + private void encodeThis() throws IOException { + DerOutputStream os = new DerOutputStream(); + + os.putUnalignedBitString(mBitString); + this.extensionValue = os.toByteArray(); + } + + /** + * Check if bit is set. + * + * @param position the position in the bit string to check. + */ + public boolean isSet(int position) { + int index = position / 8; + byte pos = (byte) (1 << (7 - (position % 8))); + + if (mBitString.length <= index) + return false; + return ((mBitString[index] & pos) != 0); + } + + /** + * Set the bit at the specified position. + */ + public void set(int position, boolean val) { + int index = position / 8; + byte pos = (byte) (1 << (7 - (position % 8))); + + if (index >= mBitString.length) { + byte[] tmp = new byte[index + 1]; + + System.arraycopy(mBitString, 0, tmp, 0, mBitString.length); + mBitString = tmp; + } + if (val) { + mBitString[index] |= pos; + } else { + mBitString[index] &= ~pos; + } + } + + /** + * Create NSCertTypeExtension from boolean array. + * The criticality is set to false. + */ + public NSCertTypeExtension(boolean critical, boolean[] bits) { + this.extensionId = CertType_Id; + this.critical = critical; + this.mBitString = new byte[0]; + + for (int i = 0; i < bits.length && i < 8; i++) { + set(i, bits[i]); + } + } + + public NSCertTypeExtension(boolean[] bits) { + this.extensionId = CertType_Id; + this.critical = false; + this.mBitString = new byte[0]; + + for (int i = 0; i < bits.length && i < 8; i++) { + set(i, bits[i]); + } + } + + /** + * Create a NSCertTypeExtension with the passed bit settings. + * The criticality is set to false. + * + * @param bitString the bits to be set for the extension. + */ + public NSCertTypeExtension(boolean critical, byte[] bitString) throws IOException { + this.mBitString = bitString; + this.extensionId = CertType_Id; + this.critical = critical; + encodeThis(); + } + + public NSCertTypeExtension(byte[] bitString) throws IOException { + this.mBitString = bitString; + this.extensionId = CertType_Id; + this.critical = false; + encodeThis(); + } + + /** + * Create the extension from the passed DER encoded value of the same. + * + * @param critical true if the extension is to be treated as critical. + * @param value Array of DER encoded bytes of the actual value. + * @exception IOException on error. + */ + public NSCertTypeExtension(Boolean critical, Object value) + throws IOException { + + /** + * Debug.trace("NSCertTypeExtension"); + * this.mBitString = new byte[1]; + * this.mBitString[0] = (byte)0x00; + * return; + **/ + + this.extensionId = CertType_Id; + this.critical = critical.booleanValue(); + byte[] extValue = (byte[]) ((byte[]) value).clone(); + + this.extensionValue = extValue; + DerValue val = new DerValue(extValue); + + this.mBitString = val.getUnalignedBitString().toByteArray(); + } + + /** + * Create a default key usage. + */ + public NSCertTypeExtension() { + this.extensionId = CertType_Id; + this.critical = false; + this.mBitString = new byte[0]; + try { + encodeThis(); + } catch (Exception e) { + } + } + + /** + * Set the attribute value. + */ + public void set(String name, Object obj) throws CertificateException { + if (!(obj instanceof Boolean)) { + throw new CertificateException("Attribute must be of type Boolean."); + } + boolean val = ((Boolean) obj).booleanValue(); + + set(getPosition(name), val); + } + + /** + * Get the attribute value. + */ + public Object get(String name) throws CertificateException { + return new Boolean(isSet(getPosition(name))); + } + + /** + * Delete the attribute value. + */ + public void delete(String name) throws CertificateException { + set(getPosition(name), false); + } + + /** + * Returns a printable representation of the NSCertType. + */ + public String toString() { + String s = super.toString() + "NSCertType [\n"; + + try { + + if (isSet(getPosition(SSL_CLIENT))) { + s += " SSL client"; + } + if (isSet(getPosition(SSL_SERVER))) { + s += " SSL server"; + } + + if (isSet(getPosition(EMAIL))) { + s += " Email"; + } + + if (isSet(getPosition(OBJECT_SIGNING))) { + s += " Object Signing"; + } + + if (isSet(getPosition(SSL_CA))) { + s += " SSL CA"; + } + + if (isSet(getPosition(EMAIL_CA))) { + s += " Email CA"; + } + + if (isSet(getPosition(OBJECT_SIGNING_CA))) { + s += " Object Signing CA"; + } + + } catch (Exception e) { + // this is reached only if there is a bug + throw new IllegalArgumentException(e.getMessage()); + } + + s += "]\n"; + + return (s); + } + + /** + * Decode the extension from the InputStream. + * + * @param in the InputStream to unmarshal the contents from. + * @exception IOException on decoding or validity errors. + */ + public void decode(InputStream in) throws IOException { + throw new IOException("Method not to be called directly."); + } + + /** + * Write the extension to the DerOutputStream. + * + * @param out the DerOutputStream to write the extension to. + * @exception IOException on encoding errors. + */ + public void encode(OutputStream out) throws IOException { + DerOutputStream tmp = new DerOutputStream(); + + encodeThis(); + if (this.extensionValue == null) { + this.extensionId = CertType_Id; + this.critical = true; + } + super.encode(tmp); + out.write(tmp.toByteArray()); + } + + /** + * Return an enumeration of names of attributes existing within this + * attribute. + */ + public Enumeration<String> getAttributeNames() { + return mAttributeNames.elements(); + } + + /** + * Return the name of this attribute. + */ + public String getName() { + return (NAME); + } + + public static void main(String[] argv) { + } +} diff --git a/base/util/src/netscape/security/extensions/OCSPNoCheckExtension.java b/base/util/src/netscape/security/extensions/OCSPNoCheckExtension.java new file mode 100644 index 000000000..28da8085f --- /dev/null +++ b/base/util/src/netscape/security/extensions/OCSPNoCheckExtension.java @@ -0,0 +1,153 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2007 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package netscape.security.extensions; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.security.cert.CertificateException; +import java.util.Enumeration; + +import netscape.security.util.DerOutputStream; +import netscape.security.util.ObjectIdentifier; +import netscape.security.x509.CertAttrSet; +import netscape.security.x509.Extension; +import netscape.security.x509.OIDMap; + +/** + * This represents the OCSPNoCheck extension. + */ +public class OCSPNoCheckExtension extends Extension implements CertAttrSet { + + /** + * + */ + private static final long serialVersionUID = -4692759557964594790L; + public static final String OID = "1.3.6.1.5.5.7.48.1.5"; + public static final String NAME = "OCSPNoCheckExtension"; + + private byte mCached[] = null; + + static { + try { + OIDMap.addAttribute(OCSPNoCheckExtension.class.getName(), + OID, NAME); + } catch (CertificateException e) { + } + } + + public OCSPNoCheckExtension() { + this(Boolean.FALSE); + } + + public OCSPNoCheckExtension(Boolean crit) { + try { + extensionId = ObjectIdentifier.getObjectIdentifier(OCSPNoCheckExtension.OID); + } catch (IOException e) { + // never here + } + critical = crit.booleanValue(); + DerOutputStream tmpD = new DerOutputStream(); + + try { + tmpD.putNull(); + } catch (IOException ex) { + } + extensionValue = tmpD.toByteArray(); + } + + public OCSPNoCheckExtension(Boolean crit, Object byteVal) { + try { + extensionId = ObjectIdentifier.getObjectIdentifier(OCSPNoCheckExtension.OID); + } catch (IOException e) { + // never here + } + critical = crit.booleanValue(); + extensionValue = (byte[]) ((byte[]) byteVal).clone(); + } + + public void setCritical(boolean newValue) { + if (critical != newValue) { + critical = newValue; + mCached = null; + } + } + + public void encode(DerOutputStream out) throws IOException { + if (mCached == null) { + super.encode(out); + mCached = out.toByteArray(); + } + } + + public String toString() { + String presentation = "oid=" + OID + " "; + + if (critical) { + presentation += "critical=true"; + } + if (extensionValue != null) { + String extByteValue = new String(" val="); + + for (int i = 0; i < extensionValue.length; i++) { + extByteValue += (extensionValue[i] + " "); + } + presentation += extByteValue; + } + return presentation; + } + + public void decode(InputStream in) + throws CertificateException, IOException { + // NOT USED + } + + public void encode(OutputStream out) + throws CertificateException, IOException { + if (mCached == null) { + DerOutputStream temp = new DerOutputStream(); + + encode(temp); + } + out.write(mCached); + } + + public void set(String name, Object obj) + throws CertificateException, IOException { + // NOT USED + } + + public Object get(String name) throws CertificateException, IOException { + // NOT USED + return null; + } + + public Enumeration<String> getAttributeNames() { + // NOT USED + return null; + } + + public String getName() { + return NAME; + } + + public void delete(String name) + throws CertificateException, IOException { + // NOT USED + } +} diff --git a/base/util/src/netscape/security/extensions/PresenceServerExtension.java b/base/util/src/netscape/security/extensions/PresenceServerExtension.java new file mode 100644 index 000000000..c67fe9965 --- /dev/null +++ b/base/util/src/netscape/security/extensions/PresenceServerExtension.java @@ -0,0 +1,321 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2007 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package netscape.security.extensions; + +import java.io.ByteArrayOutputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.security.cert.CertificateException; +import java.util.Enumeration; + +import netscape.security.util.BigInt; +import netscape.security.util.DerInputStream; +import netscape.security.util.DerOutputStream; +import netscape.security.util.DerValue; +import netscape.security.util.ObjectIdentifier; +import netscape.security.x509.CertAttrSet; +import netscape.security.x509.Extension; + +public class PresenceServerExtension extends Extension implements CertAttrSet { + /** + * + */ + private static final long serialVersionUID = -6333109673043357921L; + private boolean mCritical; + private String mOID = null; + private int mVersion = 0; + private String mStreetAddress = null; + private String mTelephoneNumber = null; + private String mRFC822Name = null; + private String mID = null; + private String mHostName = null; + private int mPortNumber = 0; + private int mMaxUsers = 0; + private int mServiceLevel = 0; + + public static final String OID = "2.16.840.1.113730.1.18"; + + /* + public PresenceServerExtension() + { + } + */ + + public PresenceServerExtension(Boolean critical, Object value) + throws IOException { + this.extensionId = new ObjectIdentifier(OID); + this.critical = critical.booleanValue(); + this.extensionValue = (byte[]) ((byte[]) value).clone(); + decodeThis(); + } + + public PresenceServerExtension( + boolean critical, + int version, + String streetAddress, + String telephoneNumber, + String rfc822Name, + String ID, + String hostName, + int portNumber, + int maxUsers, + int serviceLevel) + throws IOException { + mCritical = critical; + mVersion = version; + mStreetAddress = streetAddress; + mTelephoneNumber = telephoneNumber; + mRFC822Name = rfc822Name; + mID = ID; + mHostName = hostName; + mPortNumber = portNumber; + mMaxUsers = maxUsers; + mServiceLevel = serviceLevel; + + this.extensionId = new ObjectIdentifier(OID); + this.critical = mCritical; + encodeThis(); + } + + public int getVersion() { + return mVersion; + } + + public String getStreetAddress() { + return mStreetAddress; + } + + public String getTelephoneNumber() { + return mTelephoneNumber; + } + + public String getRFC822() { + return mRFC822Name; + } + + public String getID() { + return mID; + } + + public String getHostName() { + return mHostName; + } + + public int getPortNumber() { + return mPortNumber; + } + + public int getMaxUsers() { + return mMaxUsers; + } + + public int getServiceLevel() { + return mServiceLevel; + } + + public void encodeThis() throws IOException { + DerOutputStream out = new DerOutputStream(); + DerOutputStream temp = new DerOutputStream(); + temp.putInteger(new BigInt(mVersion)); + temp.putOctetString(mStreetAddress.getBytes()); + temp.putOctetString(mTelephoneNumber.getBytes()); + temp.putOctetString(mRFC822Name.getBytes()); + temp.putOctetString(mID.getBytes()); + temp.putOctetString(mHostName.getBytes()); + temp.putInteger(new BigInt(mPortNumber)); + temp.putInteger(new BigInt(mMaxUsers)); + temp.putInteger(new BigInt(mServiceLevel)); + out.write(DerValue.tag_Sequence, temp); + this.extensionValue = out.toByteArray(); + } + + public void decodeThis() throws IOException { + DerInputStream val = new DerInputStream(this.extensionValue); + byte data[] = null; + DerValue seq[] = val.getSequence(0); + + mVersion = seq[0].getInteger().toInt(); + data = null; + if (seq[1].length() > 0) { + data = seq[1].getOctetString(); + } + if (data == null) { + mStreetAddress = ""; + } else { + mStreetAddress = new String(data); + } + data = null; + if (seq[2].length() > 0) + data = seq[2].getOctetString(); + if (data == null) { + mTelephoneNumber = ""; + } else { + mTelephoneNumber = new String(data); + } + data = null; + if (seq[3].length() > 0) + data = seq[3].getOctetString(); + if (data == null) { + mRFC822Name = ""; + } else { + mRFC822Name = new String(data); + } + data = null; + if (seq[4].length() > 0) + data = seq[4].getOctetString(); + if (data == null) { + mID = ""; + } else { + mID = new String(data); + } + data = null; + if (seq[5].length() > 0) + data = seq[5].getOctetString(); + if (data == null) { + mHostName = ""; + } else { + mHostName = new String(data); + } + mPortNumber = seq[6].getInteger().toInt(); + mMaxUsers = seq[7].getInteger().toInt(); + mServiceLevel = seq[8].getInteger().toInt(); + } + + public void decode(InputStream in) + throws CertificateException, IOException { + } + + public void encode(OutputStream out) + throws CertificateException, IOException { + DerOutputStream dos = new DerOutputStream(); + super.encode(dos); + out.write(dos.toByteArray()); + } + + /** + * Set the attribute value. + */ + public void set(String name, Object obj) throws IOException { + throw new IOException("Method not to be called directly."); + } + + /** + * Get the attribute value. + */ + public Object get(String name) throws IOException { + return null; + } + + /** + * Delete the attribute value. + */ + public void delete(String name) throws IOException { + throw new IOException("Method not to be called directly."); + } + + public Enumeration<String> getAttributeNames() { + return null; + } + + /** + * Return the name of this attribute. + */ + public String getName() { + return "PresenceServerExtension"; + } + + /** + * Set the name of this attribute. + */ + public void setName(String name) { + } + + /** + * Return the OID of this attribute. + */ + public String getOID() { + return OID; + } + + /** + * Set the OID of this attribute. + */ + public void setOID(String oid) { + } + + public static void main(String args[]) throws Exception { + /* + 0 30 115: SEQUENCE { + 2 06 9: OBJECT IDENTIFIER '2 16 840 1 113730 1 100' + 13 04 102: OCTET STRING, encapsulates { + 15 30 100: SEQUENCE { + 17 02 1: INTEGER 0 + 20 04 31: OCTET STRING + : 34 30 31 45 20 4D 69 64 64 6C 65 66 69 65 6C 64 + : 20 52 64 2E 2C 4D 56 2C 43 41 39 34 30 34 31 + 53 04 12: OCTET STRING + : 36 35 30 2D 31 31 31 2D 31 31 31 31 + 67 04 18: OCTET STRING + : 61 64 6D 69 6E 40 6E 65 74 73 63 61 70 65 2E 63 + : 6F 6D + 87 04 10: OCTET STRING + : 70 73 2D 63 61 70 69 74 6F 6C + 99 04 7: OCTET STRING + : 63 61 70 69 74 6F 6C + 108 02 1: INTEGER 80 + 111 02 1: INTEGER 10 + 114 02 1: INTEGER 1 + : } + : } + : } + */ + boolean critical = false; + int version = 1; + String streetAddress = "401E Middlefield Rd.,MV,CA94041"; + String telephoneNumber = "650-111-1111"; + String rfc822Name = "admin@netscape.com"; + String ID = "ps-capitol"; + String hostName = "capitol"; + int portNumber = 80; + int maxUsers = 10; + int serviceLevel = 1; + + PresenceServerExtension ext = new PresenceServerExtension( + critical, + version, streetAddress, telephoneNumber, + rfc822Name, ID, hostName, portNumber, + maxUsers, serviceLevel); + + // encode + + ByteArrayOutputStream dos = new ByteArrayOutputStream(); + ext.encode(dos); + FileOutputStream fos = new FileOutputStream("pse.der"); + fos.write(dos.toByteArray()); + fos.close(); + + Extension ext1 = new Extension(new DerValue(dos.toByteArray())); + + @SuppressWarnings("unused") + PresenceServerExtension ext2 = new PresenceServerExtension( + new Boolean(false), ext1.getExtensionValue()); + + } +} diff --git a/base/util/src/netscape/security/extensions/SubjectInfoAccessExtension.java b/base/util/src/netscape/security/extensions/SubjectInfoAccessExtension.java new file mode 100644 index 000000000..5c373289f --- /dev/null +++ b/base/util/src/netscape/security/extensions/SubjectInfoAccessExtension.java @@ -0,0 +1,254 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2007 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package netscape.security.extensions; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.security.cert.CertificateException; +import java.util.Enumeration; +import java.util.Vector; + +import com.netscape.cmsutil.util.Utils; + +import netscape.security.util.DerOutputStream; +import netscape.security.util.DerValue; +import netscape.security.util.ObjectIdentifier; +import netscape.security.x509.CertAttrSet; +import netscape.security.x509.Extension; +import netscape.security.x509.GeneralName; +import netscape.security.x509.URIName; + +/** + * This represents the subject information access extension + * as defined in RFC3280. + * + * @author thomask + * @version $Revision$, $Date$ + */ +public class SubjectInfoAccessExtension extends Extension implements CertAttrSet { + private static final long serialVersionUID = 7237321566602583325L; + + public static final String NAME = "SubjectInfoAccessExtension"; + + public static final int OID_OCSP[] = { 1, 3, 6, 1, 5, 5, 7, 48, 1 }; + public static final ObjectIdentifier METHOD_OCSP = new + ObjectIdentifier(OID_OCSP); + + public static final int OID_CA_ISSUERS[] = { 1, 3, 6, 1, 5, 5, 7, 48, 2 }; + public static final ObjectIdentifier METHOD_CA_ISSUERS = new + ObjectIdentifier(OID_CA_ISSUERS); + + public static final int OID[] = { 1, 3, 6, 1, 5, 5, 7, 1, 11 }; + public static final ObjectIdentifier ID = new ObjectIdentifier(OID); + + private Vector<AccessDescription> mDesc = new Vector<AccessDescription>(); + + /** + * Create the extension from the passed DER encoded value of the same. + * + * @param critical true if the extension is to be treated as critical. + * @param value Array of DER encoded bytes of the actual value. + * @exception IOException on error. + */ + public SubjectInfoAccessExtension(boolean critical) { + this.extensionId = ID; + this.critical = critical; + this.extensionValue = null; // build this when encodeThis() is called + } + + public SubjectInfoAccessExtension(Boolean critical, Object value) + throws IOException { + this.extensionId = ID; + this.critical = critical.booleanValue(); + this.extensionValue = (byte[]) ((byte[]) value).clone(); + decodeThis(); + } + + /** + * Sets extension attribute. + */ + public void set(String name, Object obj) throws CertificateException { + // NOT USED + } + + /** + * Retrieves extension attribute. + */ + public Object get(String name) throws CertificateException { + // NOT USED + return null; + } + + /** + * Deletes attribute. + */ + public void delete(String name) throws CertificateException { + // NOT USED + } + + /** + * Decodes this extension. + */ + public void decode(InputStream in) throws IOException { + // NOT USED + } + + /** + * Return an enumeration of names of attributes existing within this + * attribute. + */ + public Enumeration<String> getAttributeNames() { + // NOT USED + return null; + } + + /** + * Return the name of this attribute. + */ + public String getName() { + return NAME; + } + + /** + * Adds Access Description. + */ + public void addAccessDescription( + ObjectIdentifier method, + GeneralName gn) { + clearValue(); + mDesc.addElement(new AccessDescription(method, gn)); + } + + public AccessDescription getAccessDescription(int pos) { + return mDesc.elementAt(pos); + } + + /** + * Returns the number of access description. + */ + public int numberOfAccessDescription() { + return mDesc.size(); + } + + private void decodeThis() throws IOException { + DerValue val = new DerValue(this.extensionValue); + + if (val.tag != DerValue.tag_Sequence) { + throw new IOException("Invalid encoding of AuthInfoAccess extension"); + } + while (val.data.available() != 0) { + DerValue seq = val.data.getDerValue(); + ObjectIdentifier method = seq.data.getDerValue().getOID(); + GeneralName gn = new GeneralName(seq.data.getDerValue()); + + addAccessDescription(method, gn); + } + } + + private void encodeThis() throws IOException { + DerOutputStream seq = new DerOutputStream(); + DerOutputStream tmp = new DerOutputStream(); + + for (int i = 0; i < mDesc.size(); i++) { + DerOutputStream tmp0 = new DerOutputStream(); + AccessDescription ad = mDesc.elementAt(i); + + tmp0.putOID(ad.getMethod()); + ad.getLocation().encode(tmp0); + tmp.write(DerValue.tag_Sequence, tmp0); + } + seq.write(DerValue.tag_Sequence, tmp); + this.extensionValue = seq.toByteArray(); + } + + /** + * Write the extension to the DerOutputStream. + * + * @param out the DerOutputStream to write the extension to. + * @exception IOException on encoding errors. + */ + public void encode(OutputStream out) throws IOException { + DerOutputStream tmp = new DerOutputStream(); + + if (this.extensionValue == null) { + encodeThis(); + } + super.encode(tmp); + out.write(tmp.toByteArray()); + } + + /** + * Returns a printable representation of the AuthInfoAccess. + */ + public String toString() { + String s = super.toString() + "AuthInfoAccess [\n"; + + for (int i = 0; i < mDesc.size(); i++) { + AccessDescription ad = mDesc.elementAt(i); + + s += "(" + i + ")"; + s += " "; + s += ad.getMethod().toString() + " " + ad.getLocation().toString(); + } + return (s + "]\n"); + } + + public static void main(String[] argv) { + AuthInfoAccessExtension aia = new AuthInfoAccessExtension(false); + GeneralName ocspName = new GeneralName(new + URIName("http://ocsp.netscape.com")); + + aia.addAccessDescription(METHOD_OCSP, ocspName); + GeneralName caIssuersName = new GeneralName(new + URIName("http://ocsp.netscape.com")); + + aia.addAccessDescription(METHOD_CA_ISSUERS, caIssuersName); + ByteArrayOutputStream os = new ByteArrayOutputStream(); + + try { + aia.encode(os); + + System.out.println(Utils.base64encode(os.toByteArray())); + } catch (IOException e) { + System.out.println(e.toString()); + } + + try { + // test serialization + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(bos); + + oos.writeObject(aia); + + ByteArrayInputStream bis = new ByteArrayInputStream( + bos.toByteArray()); + ObjectInputStream ois = new ObjectInputStream(bis); + AuthInfoAccessExtension clone = (AuthInfoAccessExtension) + ois.readObject(); + + System.out.println(clone); + } catch (Exception e) { + System.out.println(e.toString()); + } + } +} |