Coverage Report - org.openpermis.cert.AttributeCertificateExtractorUtility
 
Classes in this File Line Coverage Branch Coverage Complexity
AttributeCertificateExtractorUtility
37%
20/53
30%
8/26
3.818
 
 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  
 package org.openpermis.cert;
 11  
 
 12  
 import java.io.IOException;
 13  
 import java.io.StringReader;
 14  
 import java.net.URI;
 15  
 import java.net.URL;
 16  
 import java.security.Principal;
 17  
 import java.security.cert.CertificateException;
 18  
 import java.util.List;
 19  
 
 20  
 import javax.security.auth.x500.X500Principal;
 21  
 
 22  
 import org.bouncycastle.util.StreamParsingException;
 23  
 import org.bouncycastle.x509.X509Attribute;
 24  
 
 25  
 import org.openpermis.PolicyDecisionPoint;
 26  
 import org.openpermis.basic.AbsoluteTimePeriod;
 27  
 import org.openpermis.basic.ExpirablePolicyDecisionPoint;
 28  
 import org.openpermis.basic.TimePeriod;
 29  
 import org.openpermis.cert.RoleAttribute.RoleDefinition;
 30  
 import org.openpermis.policy.bean.basic.BasicPartBeanFactory;
 31  
 import org.openpermis.policy.io.PolicyException;
 32  
 import org.openpermis.policy.io.PolicyReader;
 33  
 import org.openpermis.policy.io.xml.PermisXmlReader;
 34  
 
 35  
 
 36  
 /**
 37  
  *
 38  
  * @since 0.3.0
 39  
  */
 40  
 public final class AttributeCertificateExtractorUtility {
 41  
 
 42  
         //---- Static
 43  
 
 44  
         /**
 45  
          * Reads a {@link TimePeriod} from an {@link AttributeCertificate}.
 46  
          * @param certificate an {@link AttributeCertificate}.
 47  
          * @return a {@link TimePeriod}.
 48  
          * @since 0.3.0
 49  
          */
 50  
         public static TimePeriod readValidityPeriod (AttributeCertificate certificate) {
 51  9
                 nullCheck(certificate);
 52  
 
 53  9
                 return new AbsoluteTimePeriod(
 54  
                         certificate.getNotBefore(),
 55  
                         certificate.getNotAfter()
 56  
                 );
 57  
         }
 58  
 
 59  
         /**
 60  
          * Reads a holder from an {@link AttributeCertificate}.
 61  
          * Currently only the entityName syntax is supported.
 62  
          * RFC 3281 allows three different (optional) holder syntaxes: baseCertificateID, entityName and
 63  
          * objectDigestInfo. The meaning is clear if exactly one holder is defined and it is not clear
 64  
          * if more than one are defined. Therefore FRC 3281 recommends to use only one.
 65  
          * @param certificate an {@link AttributeCertificate}.
 66  
          * @return an {@link X500Principal}.
 67  
          * @throws AttributeCertificateException indicates an holder reading problem.
 68  
          * @since 0.3.0
 69  
          */
 70  
         public static X500Principal readHolder (AttributeCertificate certificate)
 71  
                 throws AttributeCertificateException
 72  
         {
 73  9
                 nullCheck(certificate);
 74  
 
 75  9
                 final Principal[] principals = certificate.getHolder().getEntityNames();
 76  9
                 if (principals.length != 1) {
 77  0
                         throw new AttributeCertificateException(
 78  
                                 "AC should contain exactly one general holder name."
 79  
                         );
 80  
                 }
 81  9
                 if (!(principals[0] instanceof X500Principal)) {
 82  0
                         throw new AttributeCertificateException("AC contains an illeagal holder name.");
 83  
                 }
 84  
 
 85  9
                 return (X500Principal) principals[0];
 86  
         }
 87  
 
 88  
         /**
 89  
          * Reads a issuer from an {@link AttributeCertificate}.
 90  
          * RFC 3281 defines that exactly one general name must be specified.
 91  
          * @param certificate an {@link AttributeCertificate}.
 92  
          * @return an {@link X500Principal}.
 93  
          * @throws AttributeCertificateException indicates an issuer reading problem.
 94  
          * @since 0.3.0
 95  
          */
 96  
         public static X500Principal readIssuer (AttributeCertificate certificate)
 97  
                 throws AttributeCertificateException
 98  
         {
 99  8
                 nullCheck(certificate);
 100  
 
 101  8
                 final Principal[] principals = certificate.getIssuer().getPrincipals();
 102  8
                 if (principals.length != 1) {
 103  0
                         throw new AttributeCertificateException(
 104  
                                 "AC must contain exactly one general issuer name."
 105  
                         );
 106  
                 }
 107  8
                 if (!(principals[0] instanceof X500Principal)) {
 108  0
                         throw new AttributeCertificateException("AC contains an illeagal issuer name.");
 109  
                 }
 110  
 
 111  8
                 return (X500Principal) principals[0];
 112  
         }
 113  
 
 114  
         /**
 115  
          * Reads a policy from an {@link AttributeCertificate}.
 116  
          * @param certificate an {@link AttributeCertificate}.
 117  
          * @return the policy {@link String}.
 118  
          * @throws AttributeCertificateException indicates a reading problem.
 119  
          * @since 0.3.0
 120  
          */
 121  
         public static String readPolicyAttribute (AttributeCertificate certificate)
 122  
                 throws AttributeCertificateException
 123  
         {
 124  0
                 nullCheck(certificate);
 125  
 
 126  0
                 final X509Attribute[] attributes = certificate.getAttributes(PolicyAttribute.OID);
 127  0
                 if (attributes == null || attributes.length == 0) {
 128  0
                         throw new AttributeCertificateException("AC contains no policy attribute.");
 129  
                 }
 130  0
                 if (attributes.length > 1) {
 131  0
                         throw new AttributeCertificateException("AC contains more than one policy attribute.");
 132  
                 }
 133  
                 try {
 134  0
                         return new PolicyAttribute(attributes[0]).getPolicy();
 135  0
                 } catch (StreamParsingException e) {
 136  0
                         throw new AttributeCertificateException("AC contains invalid encoded policy.", e);
 137  
                 }
 138  
         }
 139  
 
 140  
         /**
 141  
          * Reads a {@link List} of roles from an {@link AttributeCertificate}.
 142  
          * @param certificate an {@link AttributeCertificate}.
 143  
          * @return the role {@link List}.
 144  
          * @throws AttributeCertificateException indicates a reading problem.
 145  
          * @since 0.3.0
 146  
          */
 147  
         public static List<RoleDefinition> readRoleAttribute (AttributeCertificate certificate)
 148  
                 throws AttributeCertificateException
 149  
         {
 150  9
                 nullCheck(certificate);
 151  
 
 152  9
                 final X509Attribute[] attributes = certificate.getAttributes(RoleAttribute.OID);
 153  9
                 if (attributes == null || attributes.length == 0) {
 154  0
                         throw new AttributeCertificateException("AC contains no role attribute.");
 155  
                 }
 156  9
                 if (attributes.length > 1) {
 157  0
                         throw new AttributeCertificateException("AC contains more than one role attribute.");
 158  
                 }
 159  
                 try {
 160  9
                         return new RoleAttribute(attributes[0]).getRoles();
 161  0
                 } catch (StreamParsingException e) {
 162  0
                         throw new AttributeCertificateException("AC contains invalid encoded roles.", e);
 163  
                 }
 164  
         }
 165  
 
 166  
         /**
 167  
          * Creates a policy decision point from the specified attribute certificate and verifies it
 168  
          * with the specified certificate verifier.
 169  
          *
 170  
          * @param policyCertificate The URL of the attribute certificate containing the policy.
 171  
          * @param certificateVerifier The certificate verifier used to verify the attribute certificate
 172  
          * containing the policy.
 173  
          * @return Returns the policy object.
 174  
          * @throws StreamParsingException Thrown if an attribute certificate cannot be parsed.
 175  
          * @throws IOException Thrown if the attribute certificate cannot be read.
 176  
          * @throws CertificateException Thrown if a certificate cannot be verified.
 177  
          * @throws PolicyException Thrown if the policy cannot be parsed.
 178  
          * @throws AttributeCertificateException  if the policy cannot be parsed.
 179  
          *
 180  
          * @since 0.3.0
 181  
          */
 182  
         public static PolicyDecisionPoint createPolicyDecisionPoint (
 183  
                 URL policyCertificate, CertificateVerifier certificateVerifier
 184  
         )
 185  
                 throws StreamParsingException,
 186  
                         IOException,
 187  
                         CertificateException,
 188  
                         PolicyException,
 189  
                         AttributeCertificateException
 190  
         {
 191  0
                 if (policyCertificate == null || certificateVerifier == null) {
 192  0
                         throw new IllegalArgumentException("Policy or certificate verifier is null");
 193  
                 }
 194  
 
 195  0
                 final AttributeCertificate certificate =
 196  
                         new AttributeCertificate(policyCertificate.openStream());
 197  
 
 198  0
                 final TimePeriod validity =
 199  
                         AttributeCertificateExtractorUtility.readValidityPeriod(certificate);
 200  
 
 201  
                 // Verify certificate.
 202  
                 try {
 203  0
                         certificateVerifier.verifyCertificate(certificate);
 204  0
                 } catch (Exception e) {
 205  0
                         throw new CertificateException("Could not verify policy attribute certifcate", e);
 206  0
                 }
 207  
 
 208  
                 // Get policy.
 209  0
                 final String policy = AttributeCertificateExtractorUtility.readPolicyAttribute(certificate);
 210  
 
 211  
                 // Create expirable policy.
 212  0
                 final PolicyReader reader = new PermisXmlReader(
 213  
                         new StringReader(policy), new BasicPartBeanFactory()
 214  
                 );
 215  0
                 return new ExpirablePolicyDecisionPoint(reader.readPolicy(), validity);
 216  
         }
 217  
 
 218  
         /**
 219  
          * Extracts the policy as a string from the specified attribute certificate.
 220  
          *
 221  
          * @param policyCertificate The URL of the attribute certificate containing the policy.
 222  
          * @return Returns the policy as a string.
 223  
          * @throws IOException Thrown if the attribute certificate cannot be read.
 224  
          * @throws AttributeCertificateException  if the policy cannot be parsed.
 225  
          *
 226  
          * @since 0.3.0
 227  
          */
 228  
         public static String readPolicy (URL policyCertificate)
 229  
                 throws        IOException,
 230  
                                 AttributeCertificateException
 231  
         {
 232  0
                 return AttributeCertificateExtractorUtility.readPolicyAttribute(
 233  
                         new AttributeCertificate(policyCertificate.openStream()));
 234  
         }
 235  
 
 236  
         /**
 237  
          * @since 0.3.0
 238  
          */
 239  
         public static X500Principal toX500Principal (URI uri) {
 240  0
                 return new X500Principal(uri.getPath());
 241  
         }
 242  
 
 243  
         /**
 244  
          * @since 0.3.0
 245  
          */
 246  
         public static URI toUri (X500Principal principal) {
 247  16
                 return URI.create(principal.getName("CANONICAL"));
 248  
         }
 249  
 
 250  
         /**
 251  
          * @since 0.3.0
 252  
          */
 253  
         private static void nullCheck (AttributeCertificate certificate) {
 254  35
                 if (certificate == null) {
 255  0
                         throw new IllegalArgumentException("Attribute certificate is null.");
 256  
                 }
 257  35
         }
 258  
 
 259  
         //---- Constructor
 260  
 
 261  
         /**
 262  
          * @since 0.3.0
 263  
          */
 264  0
         private AttributeCertificateExtractorUtility () {
 265  
                 // Prevents instantiation.
 266  0
         }
 267  
 
 268  
 
 269  
 }