jdk/src/share/classes/sun/security/x509/X509Cert.java
author mikejwre
Wed, 16 Dec 2009 23:39:39 -0800
changeset 4421 fcbbd4d49581
parent 715 f16baef3a20e
permissions -rw-r--r--
Merge
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
715
f16baef3a20e 6719955: Update copyright year
xdono
parents: 51
diff changeset
     2
 * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
90ce3da70b43 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Sun designates this
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
90ce3da70b43 Initial load
duke
parents:
diff changeset
     9
 * by Sun in the LICENSE file that accompanied this code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    21
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    22
 * CA 95054 USA or visit www.sun.com if you need additional information or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    23
 * have any questions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package sun.security.x509;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.io.IOException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.io.InputStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.io.OutputStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.io.ObjectInputStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import java.io.ObjectOutputStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
import java.io.Serializable;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
import java.math.BigInteger;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
import java.security.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
import java.util.Date;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
import java.util.Enumeration;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
import sun.security.util.*;     // DER
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 * @author David Brownell
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
 * @see CertAndKeyGen
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
 * @deprecated  Use the new X509Certificate class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 *              This class is only restored for backwards compatibility.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
@Deprecated
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
public class X509Cert implements Certificate, Serializable {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
    static final long serialVersionUID = -52595524744692374L;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
     * NOTE: All fields are marked transient, because we do not want them to
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
     * be included in the class description when we serialize an object of
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
     * this class. We override "writeObject" and "readObject" to use the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
     * ASN.1 encoding of a certificate as the serialized form, instead of
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
     * calling the default routines which would operate on the field values.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
     * MAKE SURE TO MARK ANY FIELDS THAT ARE ADDED IN THE FUTURE AS TRANSIENT.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
    /* The algorithm id */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
    transient protected AlgorithmId algid;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
     * Certificate data, and its envelope
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
    transient private byte rawCert [];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
    transient private byte signature [];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
    transient private byte signedCert [];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
     * X509.v1 data (parsed)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
    transient private X500Name subject; // from subject
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
    transient private PublicKey pubkey;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
    transient private Date notafter;    // from CA (constructor)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
    transient private Date notbefore;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
    transient private int version;      // from CA (signAndEncode)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
    transient private BigInteger serialnum;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
    transient private X500Name issuer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
    transient private AlgorithmId issuerSigAlg;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
     * flag to indicate whether or not this certificate has already been parsed
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
     * (through a call to one of the constructors or the "decode" or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
     * "readObject" methods). This is to ensure that certificates are
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
     * immutable.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
    transient private boolean parsed=false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
     * X509.v2 extensions
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
     * X509.v3 extensions
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
     * Other extensions ... Netscape, Verisign, SET, etc
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
     * Construct a uninitialized X509 Cert on which <a href="#decode">
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
     * decode</a> must later be called (or which may be deserialized).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
    // XXX deprecated, delete this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
    public X509Cert() { }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
     * Unmarshals a certificate from its encoded form, parsing the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
     * encoded bytes.  This form of constructor is used by agents which
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
     * need to examine and use certificate contents.  That is, this is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
     * one of the more commonly used constructors.  Note that the buffer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
     * must include only a certificate, and no "garbage" may be left at
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
     * the end.  If you need to ignore data at the end of a certificate,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
     * use another constructor.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
     * @param cert the encoded bytes, with no terminatu (CONSUMED)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
     * @exception IOException when the certificate is improperly encoded.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
    public X509Cert(byte cert []) throws IOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
        DerValue in = new DerValue (cert);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
        parse (in);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
        if (in.data.available () != 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
            throw new CertParseError ("garbage at end");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
        signedCert = cert;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
     * Unmarshals a certificate from its encoded form, parsing the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
     * encoded bytes.  This form of constructor is used by agents which
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
     * need to examine and use certificate contents.  That is, this is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
     * one of the most commonly used constructors.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
     * @param buf the buffer holding the encoded bytes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
     * @param offset the offset in the buffer where the bytes begin
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
     * @param len how many bytes of certificate exist
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
     * @exception IOException when the certificate is improperly encoded.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
    public X509Cert(byte buf [], int offset, int len) throws IOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
        DerValue in = new DerValue (buf, offset, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
        parse (in);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
        if (in.data.available () != 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
            throw new CertParseError ("garbage at end");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
        signedCert = new byte [len];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
        System.arraycopy (buf, offset, signedCert, 0, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
     * Unmarshal a certificate from its encoded form, parsing a DER value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
     * This form of constructor is used by agents which need to examine
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
     * and use certificate contents.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
     * @param derVal the der value containing the encoded cert.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
     * @exception IOException when the certificate is improperly encoded.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
    public X509Cert(DerValue derVal) throws IOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
        parse (derVal);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
        if (derVal.data.available () != 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
            throw new CertParseError ("garbage at end");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
        signedCert = derVal.toByteArray ();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
     * Partially constructs a certificate from descriptive parameters.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
     * This constructor may be used by Certificate Authority (CA) code,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
     * which later <a href="#signAndEncode">signs and encodes</a> the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
     * certificate.  Also, self-signed certificates serve as CA certificates,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
     * and are sometimes used as certificate requests.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
     * <P>Until the certificate has been signed and encoded, some of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
     * the mandatory fields in the certificate will not be available
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
     * via accessor functions:  the serial number, issuer name and signing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
     * algorithm, and of course the signed certificate.  The fields passed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
     * to this constructor are available, and must be non-null.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
     * <P>Note that the public key being signed is generally independent of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
     * the signature algorithm being used.  So for example Diffie-Hellman
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
     * keys (which do not support signatures) can be placed in X.509
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
     * certificates when some other signature algorithm (e.g. DSS/DSA,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
     * or one of the RSA based algorithms) is used.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
     * @see CertAndKeyGen
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
     * @param subjectName the X.500 distinguished name being certified
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
     * @param subjectPublicKey the public key being certified.  This
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
     *  must be an "X509Key" implementing the "PublicKey" interface.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
     * @param notBefore the first time the certificate is valid
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
     * @param notAfter the last time the certificate is valid
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
     * @exception CertException if the public key is inappropriate
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
    public X509Cert(X500Name subjectName, X509Key subjectPublicKey,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
                    Date notBefore, Date notAfter) throws CertException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
        subject = subjectName;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
        if (!(subjectPublicKey instanceof PublicKey))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
            throw new CertException (CertException.err_INVALID_PUBLIC_KEY,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
                "Doesn't implement PublicKey interface");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
        // The X509 cert API requires X509 keys, else things break.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
        pubkey = subjectPublicKey;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
        notbefore = notBefore;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
        notafter = notAfter;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
        version = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
     * Decode an X.509 certificate from an input stream.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
     * @param in an input stream holding at least one certificate
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
     * @exception IOException when the certificate is improperly encoded, or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
     * if it has already been parsed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
    public void decode(InputStream in) throws IOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
        DerValue val = new DerValue(in);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
        parse(val);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
        signedCert = val.toByteArray();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
     * Appends the certificate to an output stream.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
     * @param out an input stream to which the certificate is appended.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
     * @exception IOException when appending fails.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
    public void encode (OutputStream out) throws IOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
        { out.write (getSignedCert ()); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
     * Compares two certificates.  This is false if the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
     * certificates are not both X.509 certs, otherwise it
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
     * compares them as binary data.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
     * @param other the object being compared with this one
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
     * @return true iff the certificates are equivalent
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
    public boolean      equals (Object other)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
        if (other instanceof X509Cert)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
            return equals ((X509Cert) other);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
        else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
     * Compares two certificates, returning false if any data
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
     * differs between the two.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
     * @param other the object being compared with this one
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
     * @return true iff the certificates are equivalent
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
    public boolean      equals (X509Cert src)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
        if (this == src)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
        if (signedCert == null || src.signedCert == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
        if (signedCert.length != src.signedCert.length)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
        for (int i = 0; i < signedCert.length; i++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
            if (signedCert [i] != src.signedCert [i])
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
                return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
        return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
    /** Returns the "X.509" format identifier. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
    public String getFormat () // for Certificate
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
        { return "X.509"; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
    /** Returns <a href="#getIssuerName">getIssuerName</a> */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
    public Principal getGuarantor () // for Certificate
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
        { return getIssuerName (); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
    /** Returns <a href="#getSubjectName">getSubjectName</a> */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
    public Principal getPrincipal ()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
        { return getSubjectName (); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
     * Throws an exception if the certificate is invalid because it is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
     * now outside of the certificate's validity period, or because it
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
     * was not signed using the verification key provided.  Successfully
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
     * verifying a certificate does <em>not</em> indicate that one should
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
     * trust the entity which it represents.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
     * <P><em>Note that since this class represents only a single X.509
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
     * certificate, it cannot know anything about the certificate chain
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
     * which is used to provide the verification key and to establish trust.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
     * Other code must manage and use those cert chains.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
     * <P>For now, you must walk the cert chain being used to verify any
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
     * given cert.  Start at the root, which is a self-signed certificate;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
     * verify it using the key inside the certificate.  Then use that to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
     * verify the next certificate in the chain, issued by that CA.  In
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
     * this manner, verify each certificate until you reach the particular
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
     * certificate you wish to verify.  You should not use a certificate
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
     * if any of the verification operations for its certificate chain
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
     * were unsuccessful.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
     * </em>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
     * @param issuerPublicKey the public key of the issuing CA
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
     * @exception CertException when the certificate is not valid.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
    public void verify (PublicKey issuerPublicKey)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
    throws CertException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
        Date    now = new Date ();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
        if (now.before (notbefore))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
            throw new CertException (CertException.verf_INVALID_NOTBEFORE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
        if (now.after (notafter))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
            throw new CertException (CertException.verf_INVALID_EXPIRED);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
        if (signedCert == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
            throw new CertException (CertException.verf_INVALID_SIG,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
                "?? certificate is not signed yet ??");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
        // Verify the signature ...
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
        //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
        String          algName = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
            Signature   sigVerf = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
            algName = issuerSigAlg.getName();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
            sigVerf = Signature.getInstance(algName);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
            sigVerf.initVerify (issuerPublicKey);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
            sigVerf.update (rawCert, 0, rawCert.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
            if (!sigVerf.verify (signature)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
                throw new CertException (CertException.verf_INVALID_SIG,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
                    "Signature ... by <" + issuer + "> for <" + subject + ">");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
        // Gag -- too many catch clauses, let most through.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
        } catch (NoSuchAlgorithmException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
            throw new CertException (CertException.verf_INVALID_SIG,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
                "Unsupported signature algorithm (" + algName + ")");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
        } catch (InvalidKeyException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
            // e.printStackTrace();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
            throw new CertException (CertException.err_INVALID_PUBLIC_KEY,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
                "Algorithm (" + algName + ") rejected public key");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
        } catch (SignatureException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
            throw new CertException (CertException.verf_INVALID_SIG,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
                "Signature by <" + issuer + "> for <" + subject + ">");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
     * Creates an X.509 certificate, and signs it using the issuer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
     * passed (associating a signature algorithm and an X.500 name).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
     * This operation is used to implement the certificate generation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
     * functionality of a certificate authority.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
     * @see #getSignedCert
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
     * @see #getSigner
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
     * @see CertAndKeyGen
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
     * @param serial the serial number of the certificate (non-null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
     * @param issuer the certificate issuer (CA) (non-null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
     * @return the signed certificate, as returned by getSignedCert
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
     * @exception IOException if any of the data could not be encoded,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
     *  or when any mandatory data was omitted
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
     * @exception SignatureException on signing failures
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
    public byte []
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
    encodeAndSign (
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
        BigInteger      serial,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
        X500Signer      issuer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
    ) throws IOException, SignatureException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
        rawCert = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
         * Get the remaining cert parameters, and make sure we have enough.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
         * We deduce version based on what attribute data are available
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
         * For now, we have no attributes, so we always deduce X.509v1 !
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
        version = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
        serialnum = serial;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
        this.issuer = issuer.getSigner ();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
        issuerSigAlg = issuer.getAlgorithmId ();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
        if (subject == null || pubkey == null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
                || notbefore == null || notafter == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
            throw new IOException ("not enough cert parameters");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
         * Encode the raw cert, create its signature and put it
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
         * into the envelope.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
        rawCert = DERencode ();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
        signedCert = sign (issuer, rawCert);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
        return signedCert;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
     * Returns an X500Signer that may be used to create signatures.  Those
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
     * signature may in turn be verified using this certificate (or a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
     * copy of it).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
     * <P><em><b>NOTE:</b>  If the private key is by itself capable of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
     * creating signatures, this fact may not be recognized at this time.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
     * Specifically, the case of DSS/DSA keys which get their algorithm
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
     * parameters from higher in the certificate chain is not supportable
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
     * without using an X509CertChain API, and there is no current support
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
     * for other sources of algorithm parameters.</em>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
     * @param algorithm the signature algorithm to be used.  Note that a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
     *  given public/private key pair may support several such algorithms.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
     * @param privateKey the private key used to create the signature,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
     *  which must correspond to the public key in this certificate
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
     * @return the Signer object
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
     * @exception NoSuchAlgorithmException if the signature
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
     *  algorithm is not supported
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
     * @exception InvalidKeyException if either the key in the certificate,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
     *  or the private key parameter, does not support the requested
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
     *  signature algorithm
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
    public X500Signer   getSigner (AlgorithmId algorithmId,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
                                   PrivateKey privateKey)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
    throws NoSuchAlgorithmException, InvalidKeyException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
        String algorithm;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
        Signature       sig;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
        if (privateKey instanceof Key) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
            Key key = (Key)privateKey;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
            algorithm = key.getAlgorithm();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
            throw new InvalidKeyException("private key not a key!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
        sig = Signature.getInstance(algorithmId.getName());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
        if (!pubkey.getAlgorithm ().equals (algorithm)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
          throw new InvalidKeyException( "Private key algorithm " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
                                         algorithm +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
                                         " incompatible with certificate " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
                                         pubkey.getAlgorithm());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
        sig.initSign (privateKey);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
        return new X500Signer (sig, subject);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
     * Returns a signature object that may be used to verify signatures
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
     * created using a specified signature algorithm and the public key
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
     * contained in this certificate.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
     * <P><em><b>NOTE:</b>  If the public key in this certificate is not by
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
     * itself capable of verifying signatures, this may not be recognized
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
     * at this time.  Specifically, the case of DSS/DSA keys which get
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
     * their algorithm parameters from higher in the certificate chain
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
     * is not supportable without using an X509CertChain API, and there
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
     * is no current support for other sources of algorithm parameters.</em>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
     * @param algorithm the algorithm of the signature to be verified
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
     * @return the Signature object
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
     * @exception NoSuchAlgorithmException if the signature
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
     *  algorithm is not supported
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
     * @exception InvalidKeyException if the key in the certificate
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
     *  does not support the requested signature algorithm
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
    public Signature getVerifier(String algorithm)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
    throws NoSuchAlgorithmException, InvalidKeyException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
        String          algName;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
        Signature       sig;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
        sig = Signature.getInstance(algorithm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
        sig.initVerify (pubkey);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
        return sig;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
     * Return the signed X.509 certificate as a byte array.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
     * The bytes are in standard DER marshaled form.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
     * Null is returned in the case of a partially constructed cert.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
    public byte []      getSignedCert ()
51
6fe31bc95bbc 6600143: Remove another 450 unnecessary casts
martin
parents: 2
diff changeset
   519
        { return signedCert.clone(); }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
     * Returns the certificate's serial number.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
     * Null is returned in the case of a partially constructed cert.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
    public BigInteger   getSerialNumber ()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
        { return serialnum; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
     * Returns the subject's X.500 distinguished name.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
    public X500Name     getSubjectName ()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
        { return subject; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
     * Returns the certificate issuer's X.500 distinguished name.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
     * Null is returned in the case of a partially constructed cert.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
    public X500Name     getIssuerName ()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
        { return issuer; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
     * Returns the algorithm used by the issuer to sign the certificate.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
     * Null is returned in the case of a partially constructed cert.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
    public AlgorithmId  getIssuerAlgorithmId ()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
        { return issuerSigAlg; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
     * Returns the first time the certificate is valid.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
    public Date getNotBefore ()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
        { return new Date(notbefore.getTime()); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
     * Returns the last time the certificate is valid.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
    public Date getNotAfter ()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
        { return new Date(notafter.getTime()); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
     * Returns the subject's public key.  Note that some public key
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
     * algorithms support an optional certificate generation policy
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
     * where the keys in the certificates are not in themselves sufficient
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
     * to perform a public key operation.  Those keys need to be augmented
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
     * by algorithm parameters, which the certificate generation policy
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
     * chose not to place in the certificate.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
     * <P>Two such public key algorithms are:  DSS/DSA, where algorithm
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
     * parameters could be acquired from a CA certificate in the chain
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
     * of issuers; and Diffie-Hellman, with a similar solution although
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
     * the CA then needs both a Diffie-Hellman certificate and a signature
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
     * capable certificate.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
    public PublicKey            getPublicKey ()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
        { return pubkey; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
     * Returns the X.509 version number of this certificate, zero based.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
     * That is, "2" indicates an X.509 version 3 (1993) certificate,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
     * and "0" indicates X.509v1 (1988).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
     * Zero is returned in the case of a partially constructed cert.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
    public int          getVersion ()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
        { return version; }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
     * Calculates a hash code value for the object.  Objects
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
     * which are equal will also have the same hashcode.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
    public int          hashCode ()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
        int     retval = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
        for (int i = 0; i < signedCert.length; i++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
            retval += signedCert [i] * i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
        return retval;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
     * Returns a printable representation of the certificate.  This does not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
     * contain all the information available to distinguish this from any
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
     * other certificate.  The certificate must be fully constructed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
     * before this function may be called; in particular, if you are
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
     * creating certificates you must call encodeAndSign() before calling
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
     * this function.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
    public String       toString ()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
        String          s;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
        if (subject == null || pubkey == null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
                || notbefore == null || notafter == null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
                || issuer == null || issuerSigAlg == null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
                || serialnum == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
            throw new NullPointerException ("X.509 cert is incomplete");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
        s = "  X.509v" + (version + 1) + " certificate,\n";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
        s += "  Subject is " + subject + "\n";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
        s += "  Key:  " + pubkey;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
        s += "  Validity <" + notbefore + "> until <" + notafter + ">\n";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
        s += "  Issuer is " + issuer + "\n";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
        s += "  Issuer signature used " + issuerSigAlg.toString () + "\n";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
        s += "  Serial number = " + Debug.toHexString(serialnum) + "\n";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
        // optional v2, v3 extras
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
        return "[\n" + s + "]";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
     * Returns a printable representation of the certificate.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
     * @param detailed true iff lots of detail is requested
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
    public String       toString (boolean detailed)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
        { return toString (); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
    /************************************************************/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
     * Cert is a SIGNED ASN.1 macro, a three elment sequence:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
     *  - Data to be signed (ToBeSigned) -- the "raw" cert
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
     *  - Signature algorithm (SigAlgId)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
     *  - The signature bits
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
     * This routine unmarshals the certificate, saving the signature
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
     * parts away for later verification.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
    private void parse (DerValue val) throws IOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
        if (parsed == true) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
            throw new IOException("Certificate already parsed");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
        DerValue seq [] = new DerValue [3];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
        seq [0] = val.data.getDerValue ();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
        seq [1] = val.data.getDerValue ();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
        seq [2] = val.data.getDerValue ();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
        if (val.data.available () != 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
            throw new CertParseError ("signed overrun, bytes = "
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
                    + val.data.available ());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
        if (seq [0].tag != DerValue.tag_Sequence)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
            throw new CertParseError ("signed fields invalid");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
        rawCert = seq [0].toByteArray ();       // XXX slow; fixme!
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
        issuerSigAlg = AlgorithmId.parse (seq [1]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
        signature = seq [2].getBitString ();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
        if (seq [1].data.available () != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
            // XXX why was this error check commented out?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
            // It was originally part of the next check.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
            throw new CertParseError ("algid field overrun");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
        if (seq [2].data.available () != 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
            throw new CertParseError ("signed fields overrun");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
         * Let's have fun parsing the cert itself.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
        DerInputStream  in;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
        DerValue        tmp;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
        in = seq [0].data;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
         * Version -- this is optional (default zero). If it's there it's
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
         * the first field and is specially tagged.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
         * Both branches leave "tmp" holding a value for the serial
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
         * number that comes next.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
        version = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
        tmp = in.getDerValue ();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
        if (tmp.isConstructed () && tmp.isContextSpecific ()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
            version = tmp.data.getInteger();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
            if (tmp.data.available () != 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
                throw new IOException ("X.509 version, bad format");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
            tmp = in.getDerValue ();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
         * serial number ... an integer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
        serialnum = tmp.getBigInteger ();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
         * algorithm type for CA's signature ... needs to match the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
         * one on the envelope, and that's about it!  different IDs
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
         * may represent a signature attack.  In general we want to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
         * inherit parameters.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
        tmp = in.getDerValue ();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
            AlgorithmId         algid;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
            algid = AlgorithmId.parse(tmp);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
            if (!algid.equals (issuerSigAlg))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
                throw new CertParseError ("CA Algorithm mismatch!");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
            this.algid = algid;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
         * issuer name
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
        issuer = new X500Name (in);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
         * validity:  SEQUENCE { start date, end date }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
        tmp = in.getDerValue ();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
        if (tmp.tag != DerValue.tag_Sequence)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
            throw new CertParseError ("corrupt validity field");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
        notbefore = tmp.data.getUTCTime ();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
        notafter = tmp.data.getUTCTime ();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
        if (tmp.data.available () != 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
            throw new CertParseError ("excess validity data");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
         * subject name and public key
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
        subject = new X500Name (in);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
        tmp = in.getDerValue ();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
        pubkey = X509Key.parse (tmp);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
         * XXX for v2 and later, a bunch of tagged options follow
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
        if (in.available () != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
             * Until we parse V2/V3 data ... ignore it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
             *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
            // throw new CertParseError ("excess cert data");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
            System.out.println (
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
                    "@end'o'cert, optional V2/V3 data unparsed:  "
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
                    + in.available ()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
                    + " bytes"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
                    );
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
            */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
        parsed = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
     * Encode only the parts that will later be signed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
    private byte [] DERencode () throws IOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
        DerOutputStream raw = new DerOutputStream ();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
        encode (raw);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
        return raw.toByteArray ();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
     * Marshal the contents of a "raw" certificate into a DER sequence.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
    private void encode (DerOutputStream out) throws IOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
        DerOutputStream tmp = new DerOutputStream ();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
         * encode serial number, issuer signing algorithm,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
         * and issuer name into the data we'll return
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
        tmp.putInteger (serialnum);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
        issuerSigAlg.encode (tmp);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
        issuer.encode (tmp);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
         * Validity is a two element sequence ... encode the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
         * elements, then wrap them into the data we'll return
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
        {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
            DerOutputStream     seq = new DerOutputStream ();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
            seq.putUTCTime (notbefore);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
            seq.putUTCTime (notafter);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
            tmp.write (DerValue.tag_Sequence, seq);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
         * Encode subject (principal) and associated key
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
        subject.encode (tmp);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
        tmp.write(pubkey.getEncoded());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
         * Wrap the data; encoding of the "raw" cert is now complete.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
        out.write (DerValue.tag_Sequence, tmp);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
     * Calculate the signature of the "raw" certificate,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
     * and marshal the cert with the signature and a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
     * description of the signing algorithm.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
    private byte [] sign (X500Signer issuer, byte data [])
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
    throws IOException, SignatureException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   849
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
         * Encode the to-be-signed data, then the algorithm used
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
         * to create the signature.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
        DerOutputStream out = new DerOutputStream ();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
        DerOutputStream tmp = new DerOutputStream ();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
        tmp.write (data);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
        issuer.getAlgorithmId ().encode(tmp);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
         * Create and encode the signature itself.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
        issuer.update (data, 0, data.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
        signature = issuer.sign ();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
        tmp.putBitString (signature);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
         * Wrap the signed data in a SEQUENCE { data, algorithm, sig }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
        out.write (DerValue.tag_Sequence, tmp);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   871
        return out.toByteArray ();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   872
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   873
90ce3da70b43 Initial load
duke
parents:
diff changeset
   874
90ce3da70b43 Initial load
duke
parents:
diff changeset
   875
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   876
     * Serialization write ... X.509 certificates serialize as
90ce3da70b43 Initial load
duke
parents:
diff changeset
   877
     * themselves, and they're parsed when they get read back.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   878
     * (Actually they serialize as some type data from the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   879
     * serialization subsystem, then the cert data.)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   880
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   881
    private void writeObject (java.io.ObjectOutputStream stream)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   882
        throws IOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   883
        { encode(stream); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   884
90ce3da70b43 Initial load
duke
parents:
diff changeset
   885
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   886
     * Serialization read ... X.509 certificates serialize as
90ce3da70b43 Initial load
duke
parents:
diff changeset
   887
     * themselves, and they're parsed when they get read back.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   888
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   889
    private void readObject (ObjectInputStream stream)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   890
        throws IOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   891
        { decode(stream); }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   892
}