Coverage Report - org.openpermis.cert.AttributeCertificate
 
Classes in this File Line Coverage Branch Coverage Complexity
AttributeCertificate
70%
26/37
66%
4/6
1.294
 
 1  
 /*
 2  
  * Copyright (c) 2009, Swiss Federal Department of Defence Civil Protection and Sport
 3  
  *                     (http://www.vbs.admin.ch)
 4  
  * Copyright (c) 2009, Ergon Informatik AG (http://www.ergon.ch)
 5  
  * All rights reserved.
 6  
  *
 7  
  * Licensed under the Open Permis License which accompanies this distribution,
 8  
  * and is available at http://www.openpermis.org/BSDlicenceKent.txt
 9  
  */
 10  
 
 11  
 package org.openpermis.cert;
 12  
 
 13  
 import java.io.ByteArrayInputStream;
 14  
 import java.io.ByteArrayOutputStream;
 15  
 import java.io.IOException;
 16  
 import java.io.InputStream;
 17  
 import java.security.InvalidKeyException;
 18  
 import java.security.NoSuchAlgorithmException;
 19  
 import java.security.NoSuchProviderException;
 20  
 import java.security.PublicKey;
 21  
 import java.security.Signature;
 22  
 import java.security.SignatureException;
 23  
 import java.security.cert.Certificate;
 24  
 import java.security.cert.CertificateEncodingException;
 25  
 import java.security.cert.CertificateException;
 26  
 import java.security.cert.X509Extension;
 27  
 import java.util.Date;
 28  
 import java.util.Set;
 29  
 
 30  
 import org.bouncycastle.asn1.ASN1InputStream;
 31  
 import org.bouncycastle.x509.AttributeCertificateHolder;
 32  
 import org.bouncycastle.x509.AttributeCertificateIssuer;
 33  
 import org.bouncycastle.x509.X509Attribute;
 34  
 import org.bouncycastle.x509.X509AttributeCertificate;
 35  
 import org.bouncycastle.x509.X509V2AttributeCertificate;
 36  
 
 37  
 /**
 38  
  * This class represents an attribute certificate.
 39  
  * 
 40  
  * Since there is no equivalent in the Java JCE, this implementation uses some code if the 
 41  
  * Bouncycastle cryptographic library but also implements {@link java.security.cert.Certificate}.
 42  
  * The used Bouncycastle library uses itself the JCE for cryptographic operations such as 
 43  
  * digital signature verification.
 44  
  * @since 0.3.0
 45  
  */
 46  
 public class AttributeCertificate extends Certificate implements X509Extension {
 47  
 
 48  
         //---- Static
 49  
         
 50  
         private static final long serialVersionUID = 1L;
 51  
         
 52  
         private static final int INTERNAL_BUFFER_SIZE = 1024;
 53  
         
 54  
         //---- State
 55  
         
 56  
         /**
 57  
          * Byte array with the ASN1 representation of the attribute certificate.
 58  
          */
 59  
         private byte[] encoded; 
 60  
         
 61  
         /** 
 62  
          * The ASN1 decoded certificate structure (used to access the issuer public key).
 63  
          */
 64  
         private org.bouncycastle.asn1.x509.AttributeCertificate asnDecoded;
 65  
         
 66  
         /** 
 67  
          * The attribute certificate itself (no access to issuer public key).
 68  
          */
 69  
         private X509AttributeCertificate ac; 
 70  
                 
 71  
         //---- Constructor
 72  
         
 73  
         /**
 74  
          * Decodes an X.509 attribute certificate from the given DER stream (ASN.1 representation) of
 75  
          * the certificate.
 76  
          * 
 77  
          * @param derStream The input stream containing the DER encoded certificate.
 78  
          * @throws IOException Thrown if the stream cannot be read or the certificate cannot be 
 79  
          * decoded.
 80  
          */
 81  
         public AttributeCertificate (InputStream derStream) throws IOException {
 82  17
                 super("X.509");
 83  17
                 if (derStream == null) {
 84  0
                         throw new IllegalArgumentException("derStream is null");
 85  
                 }
 86  
                 
 87  
                 // Read stream into array.
 88  17
                 ByteArrayOutputStream baos = new ByteArrayOutputStream();
 89  17
                 byte[] buffer = new byte[INTERNAL_BUFFER_SIZE];
 90  17
                 int readBytes = 0;
 91  34
                 while ((readBytes = derStream.read(buffer)) > -1) {
 92  17
                         baos.write(buffer, 0, readBytes);
 93  
                 }
 94  17
                 this.encoded = baos.toByteArray();
 95  17
                 this.asnDecoded = org.bouncycastle.asn1.x509.AttributeCertificate.getInstance(
 96  
                         new ASN1InputStream(new ByteArrayInputStream(this.encoded)).readObject()
 97  
                 );
 98  16
                 this.ac = new X509V2AttributeCertificate(this.encoded);
 99  16
         }
 100  
 
 101  
         /**
 102  
          * Decodes an X.509 attribute certificate from the given byte array representing a DER encoded
 103  
          * (ASN.1 representation) certificate.
 104  
          * 
 105  
          * @param derEncoded A byte array containing the DER encoded certificate.
 106  
          * @throws IOException Thrown if the certificate cannot be decoded.
 107  
          */
 108  
         public AttributeCertificate (byte[] derEncoded) throws IOException {
 109  7
                 super("X.509");
 110  7
                 if (derEncoded == null) {
 111  0
                         throw new IllegalArgumentException("derEncoded is null");
 112  
                 }
 113  7
                 this.encoded = derEncoded;
 114  7
                 this.asnDecoded = org.bouncycastle.asn1.x509.AttributeCertificate.getInstance(
 115  
                         new ASN1InputStream(new ByteArrayInputStream(this.encoded)).readObject()
 116  
                 );
 117  7
                 this.ac = new X509V2AttributeCertificate(this.encoded);
 118  7
         }
 119  
         
 120  
         //---- Methods
 121  
         
 122  
         /**
 123  
          * Return the date before which the certificate is not valid.
 124  
          * 
 125  
          * @return the "not valid before" date.
 126  
          * @since 0.3.0
 127  
          */
 128  
         public Date getNotBefore () {
 129  9
                 return this.ac.getNotBefore();
 130  
         }
 131  
 
 132  
         /**
 133  
          * Return the date after which the certificate is not valid.
 134  
          * 
 135  
          * @return the "not valid afer" date.
 136  
          * @since 0.3.0
 137  
          */
 138  
         public Date getNotAfter () {
 139  9
                 return this.ac.getNotAfter();
 140  
         }
 141  
         
 142  
         /**
 143  
          * Return the attributes contained in the attribute block in the certificate.
 144  
          * 
 145  
          * @return An array of attributes.
 146  
          * @since 0.3.0
 147  
          */
 148  
         public X509Attribute[] getAttributes () {
 149  0
                 return this.ac.getAttributes();
 150  
         }
 151  
         
 152  
         /**
 153  
          * Return the attributes with the same type as the passed in oid.
 154  
          * 
 155  
          * @param oid the object identifier we wish to match.
 156  
          * @return an array of matched attributes, null if there is no match.
 157  
          */
 158  
         public X509Attribute[] getAttributes (String oid) {
 159  10
                 return this.ac.getAttributes(oid);
 160  
         }
 161  
         
 162  
         /**
 163  
          * Return the issuer details for the certificate.
 164  
          * 
 165  
          * @return the issuer details.
 166  
          * @since 0.3.0
 167  
          */
 168  
         public AttributeCertificateIssuer getIssuer () {
 169  11
                 return this.ac.getIssuer();
 170  
         }
 171  
         
 172  
         /**
 173  
          * Return the holder of the certificate.
 174  
          * 
 175  
          * @return the holder.
 176  
          * @since 0.3.0
 177  
          */
 178  
         public AttributeCertificateHolder getHolder () {
 179  12
                 return this.ac.getHolder();
 180  
         }
 181  
         
 182  
         //---- java.security.cert.Certificate 
 183  
         
 184  
         /**
 185  
          * @since 0.3.0
 186  
          */
 187  
         @Override
 188  
         public byte[] getEncoded () throws CertificateEncodingException {
 189  2
                 return this.encoded;
 190  
         }
 191  
 
 192  
         /**
 193  
          * @since 0.3.0
 194  
          */
 195  
         @Override
 196  
         public PublicKey getPublicKey () {
 197  0
                 return null;
 198  
         }
 199  
 
 200  
         /**
 201  
          * @since 0.3.0
 202  
          */
 203  
         @Override
 204  
         public String toString () {
 205  0
                 return this.ac.toString();
 206  
         }
 207  
 
 208  
         /**
 209  
          * @since 0.3.0
 210  
          */
 211  
         @Override
 212  
         public void verify (PublicKey publicKey) 
 213  
                 throws 
 214  
                         CertificateException, 
 215  
                         NoSuchAlgorithmException,
 216  
                         InvalidKeyException,
 217  
                         NoSuchProviderException, 
 218  
                         SignatureException
 219  
         {
 220  
                 // Determine provider that BC will use (because BC does not provide this method).
 221  17
                 Signature signature = 
 222  
                         Signature.getInstance(this.asnDecoded.getSignatureAlgorithm().getObjectId().getId());        
 223  17
                 this.ac.verify(publicKey, signature.getProvider().getName());
 224  11
         }
 225  
 
 226  
         /**
 227  
          * @since 0.3.0
 228  
          */
 229  
         @Override
 230  
         public void verify (PublicKey publicKey, String provider) 
 231  
                 throws 
 232  
                         CertificateException, 
 233  
                         NoSuchAlgorithmException, 
 234  
                         InvalidKeyException, 
 235  
                         NoSuchProviderException, 
 236  
                         SignatureException 
 237  
         {
 238  0
                 this.ac.verify(publicKey, provider);
 239  0
         }
 240  
 
 241  
         //---- java.security.cert.X509Extension  
 242  
         
 243  
         /**
 244  
          * @since 0.3.0
 245  
          */
 246  
         public Set<String> getCriticalExtensionOIDs () {
 247  0
                 return this.ac.getCriticalExtensionOIDs();
 248  
         }
 249  
 
 250  
         /**
 251  
          * @since 0.3.0
 252  
          */
 253  
         public byte[] getExtensionValue (String arg0) {
 254  0
                 return this.ac.getExtensionValue(arg0);
 255  
         }
 256  
 
 257  
         /**
 258  
          * @since 0.3.0
 259  
          */
 260  
         public Set<String> getNonCriticalExtensionOIDs () {
 261  0
                 return this.ac.getNonCriticalExtensionOIDs();
 262  
         }
 263  
 
 264  
         /**
 265  
          * @since 0.3.0
 266  
          */
 267  
         public boolean hasUnsupportedCriticalExtension () {
 268  0
                 return this.ac.hasUnsupportedCriticalExtension();
 269  
         }
 270  
         
 271  
 }