Java Cryptography & Attribute Certificate Management

Since Java doesn't support attribute certificate generation and management, our authors built a provider called IMPCS that does.


September 07, 2006
URL:http://www.drdobbs.com/jvm/java-cryptography-attribute-certificate/192600528

Snezana is a researcher at Belgrade's Institute Mihailo Pupin and can be contacted at [email protected]. Zoran is director of the Belgrade University Computing Center.


X.509 is an ITU recommendation for defining digital certificates (www.ietf.org/html.charters/pkix-charter.html). Originally, X.509 certificates were meant to provide nonforgeable evidence of a person's identity. Consequently, X.509 certificates contain information about certificate owners, such as their name and public key, signed by Certificate Authority (CA). However, it quickly became evident that in many situations, information about a person's privileges or attributes can be much more important than that of their identity. Thus, for example, on an e-commerce B2B site, entrance may be restricted to those who are members of a certain commercial organization, or who have paid a certain membership to a professional association. In such contexts, the authorization process is not based on identity, but rather on attributes.

This led to the addition of a new field in the third edition of X.509 (1997)—extensions that could hold any data. Many systems have taken advantage of this to introduce additional information (such as privileges) in private extension fields. However, the somewhat haphazard manner in which this occurred has led to a fragmented system, which lacks some interoperability, jurisdiction, and revocation functionality. If revocation of one privilege is needed, the whole certificate must be revoked. Furthermore, it is more appropriate that attributes (privileges) are assigned by organizations that are "direct owners" of this information—universities for registered students, medical associations for health professionals, and so on—than that CAs assign it.

Therefore, in the fourth edition of the X.509 Standard (2000), the definition of an attribute certificate (AC) was introduced to distinguish it from public-key certificates (PKC) from previous versions of the X.509 Standard. Attribute Authority (AA) provides AC and signs it using its own private key. AC is bounded to PKC because the field holder in an attribute certificate contains a serial number and the X500 name of the public-key certificate's issuer; see Tables 1 and 2.

Field Value
Version V1
Holder: Issuer CN=Certificate Authority, O=IMP C=SCG
Holder: SerialNumber 123456789
Issuer CN=Attribute Authority, O=IMP, C=SCG
Signature dsaWithMD5
SerialNumber 987654321
ValidityPeriod January 1, 2005-January 1, 2007
Attributes Type 2.5.4.72 (role)
Value Manager
SignatureValue A765 E543 ...

Table 1: Attribute certificate.

Field Value
Version V3
serialNumber 123456789
Signature dsaWithMD5
Issuer CN=Attribute Authority, O=IMP, C=SCG
ValidityPeriod January 1, 2005-January 1, 2007
SubjectPublicKeyInfo DSA Encryption
A765 E543 ...
...

Table 2: Public-key certificate.

X.509 supports discretionary, mandatory, and role-based access control (MAC, DAC, and RBAC). X.509 supports RBAC by defining role specification ACs (RSAC) that hold permissions granted to each role, and role assignment ACs (RAAC) that assign various roles to the users. In role specification ACs, the holder is the role and the privilege attributes are permissions granted to the role.

Java 2 SDK supports:

However, Java doesn't support attribute certificate generation and management. Therefore, we've implemented a provider named IMPCS ("Institute Mihailo Pupin Computer Systems") that works with attribute certificates.

Implementing The Provider

The Java Crypto API is a provider-based framework that provides a partial functionality (Certificate Management, Digital Signing) and is independent of algorithms, and there exist providers that implement the algorithm. The term "provider" refers to a package (or a set of packages) that supplies a concrete implementation of a subset of the cryptography aspects. In our implementation, package jace1.* (short for "Java Attribute Certificate Extension") contains classes that extend classes from package sun.security.X509.*:

Package jace1.* also contains Holder, see Listings One(a) and One(b); and AttributeAC, Listings Two(a) and Two(b); which are classes that correspond to fields Holder and Attribute. Class X509RAACCertInfo contains methods for encoding AC fields into an output stream and parsing AC fields from an input stream. In all classes, encoding in an output stream has been achieved using Distinguished Encoding Rules (DER). Bytes that contain encoded fields are preceded by DerTag, which denotes if it is INTEGER, STRING, SEQUENCE, and so on.

(a)
package jace1;
import sun.security.x509.*;
public class HolderAttrCert {
     private CertificateIssuerName issuer;
     private SerialNumber serNumber;
     public  HolderAttrCert(X500Name name, SerialNumber num) {
        issuer = new CertificateIssuerName(name);
        serNumber = num;
     }
     public CertificateIssuerName getIssuer(){
        return issuer;
     }
     public SerialNumber getSerNumber(){
        return serNumber;
     }
}

(b)
package jace1;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import sun.security.util.*;
import sun.security.x509.*;

public class Holder {
    private HolderAttrCert  holding;
    // Construct the class from the DerValue
    private void construct(DerValue derVal) throws IOException {
        parse(derVal);
        if (derVal.data.available() != 0) {
            throw new IOException("Excess Holder data");
        }
    }
    public Holder(X500Name name, SerialNumber serNumber) {
        holding = new HolderAttrCert(name, serNumber);
    }
    public Holder(DerInputStream in) throws IOException {
        DerValue derVal = in.getDerValue();
        construct(derVal);
    }
    public Holder(DerValue val) throws IOException {
        construct(val);
    }
    public Holder(InputStream in) throws IOException {
        DerValue derVal = new DerValue(in);
        construct(derVal);
    }
    public void encode(DerOutputStream out) throws IOException {
        DerOutputStream tmp = new DerOutputStream ();
        holding.getIssuer().encode(tmp);
        holding.getSerNumber().encode(tmp);

    out.write (DerValue.tag_Sequence, tmp);

    }
    public HolderAttrCert getHolderAttrCert() {
        return holding;
    }
    private void parse (DerValue val) throws IOException
    {
    DerValue seq [] = new DerValue [2];

    seq [0] = val.data.getDerValue ();
    seq [1] = val.data.getDerValue ();

    X500Name issuer = new X500Name(seq [0]);
    SerialNumber serNumber = new SerialNumber(seq[1]);

    holding = new HolderAttrCert(issuer, serNumber);
    }
}
Listing One

(a)
package jace1;
import sun.security.util.ObjectIdentifier;
public class AttributeInAttrCert {
     private ObjectIdentifier oi;
     private String  value;
     public  AttributeInAttrCert(ObjectIdentifier oId, String aValue) {
        oi = oId;
        value = aValue;
     }
     public ObjectIdentifier getObjectIdentifier(){
        return oi;
     }
     public String getValue(){
        return value;
     }
}

(b)
package jace1;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;

import sun.security.util.*;
import sun.security.x509.*;
public class AttributeAC {
    private AttributeInAttrCert attribute;
    // Construct the class from the DerValue
    private void construct(DerValue derVal) throws IOException {
        parse(derVal);
        if (derVal.data.available() != 0) {
            throw new IOException("Excess Holder data");
        }
    }
    public AttributeAC(ObjectIdentifier oi, String value) {
        attribute = new AttributeInAttrCert(oi, value);
    }
    public AttributeAC(DerInputStream in) throws IOException {
        DerValue derVal = in.getDerValue();
        construct(derVal);
    }
    public AttributeAC(DerValue val) throws IOException {
        construct(val);
    }
    public AttributeAC(InputStream in) throws IOException {
        DerValue derVal = new DerValue(in);
        construct(derVal);
    }
    public void encode(DerOutputStream out) throws IOException {
        DerOutputStream tmp = new DerOutputStream ();
        tmp.putOID(attribute.getObjectIdentifier());
        tmp.putPrintableString(attribute.getValue());
        out.write(DerValue.tag_Sequence, tmp);
    }
    public AttributeInAttrCert getAttributeInAttrCert() {
        return attribute;
    }
    private void parse (DerValue val) throws IOException
    {
    DerValue seq [] = new DerValue [2];

    seq [0] = val.data.getDerValue ();
    seq [1] = val.data.getDerValue ();

    ObjectIdentifier oi = (seq [0]).getOID();
    String value = seq[1].getPrintableString();
        attribute = new AttributeInAttrCert(oi, value);

     }
}
Listing Two

The Role Specification Attribute Certificate could contain privileges as plaintext or XML files, while field RSACHolder is of String type. In our application, RAAC has been implemented in package jace1.*, while RSAC has been implemented in package jace2.*.

Package acgen.* contains two applications:

[Click image to view at full size]

Figure 1: acgen.ACGenApplication frame.

[Click image to view at full size]

Figure 2: acgen.ACReadApplication frame.

Package acgen2.* also contains two applications:

[Click image to view at full size]

Figure 3: acgen2.ACGenApplication frame.

[Click image to view at full size]

Figure 4: acgen2.ACReadApplication frame.

It is also necessary to generate CA keys. This can be done using AppletGenerateCAKeys (see our article "Java Cryptography & X.509 Authentication," http://www.ddj.com/184405961).

The IMPCS provider can be installed by adding classes to CLASSPATH.

Class IMPCS extends the java.security .Provider class and provides mapping of service name to the name of class that implements service (Listing Three). Therefore, service RAAC certificate type generation uses class jace1.X509RAACFactory, while service RSAC certificate type generation uses class jace2.X509RSACFactory.


package jace1;
import java.io.*;
import java.util.*;
import java.security.*;
import sun.security.provider.*;

public class IMPCS extends Provider {
    private static final String INFO = 
        "IMPCS " + "Attribute Certificates Management";
    public IMPCS() {
        super("IMPCS", 1.0, INFO);
        AccessController.doPrivileged(
            new java.security.PrivilegedAction()
            {
                public Object run() {
                    put("CertificateFactory.RAC", 
                        "jace1.X509RAACFactory");
                    put("CertificateFactory.RSC", 
                        "jace2.X509RSACFactory");
                    return null;
                }
            }
        );
    }
}
Listing Three

To implement a cryptographic service, you need to create a subclass of the appropriate Service Provider Interface (SPI) class. SPI defines methods that cryptographic service providers must implement. This includes SignatureSpi, MessageDigestSpi, KeyPairGeneratorSpi, SecureRandomSpi, AlgorithmParameterGeneratorSpi, AlgorithmParametersSpi, KeyFactorySpi, CertificateFactorySpi, and KeyStoreSpi. Class X509RAACFactory extends X509Factory, which extends CertificateFactorySPI.

The IMPCS provider is added dynamically:

Security.addProvider 	      (new jace1.IMPCS());

while the RAAC type of certificate generation from file attributeCertificate1 has these calls:

CertificateFactory cf = 
   CertificateFactory.getInstance
    ("RAAC", "IMPCS");
Certificate cert = 
  (X509RoleAssignmentCertificate) 
   cf.generateCertificate(new File     ("attributeCertificate1"));


The method Security.addProvider() in class Security.java invokes method Provider.loadProvider(name). Class java.security.Provider extends class java.util.Properties. Properties are used to find where a particular service is implemented. For example, service CertificateFactory.RAAC is implemented in jace1.X509RAACFactory.

Conclusion

In this article and the accompanying code, we present the implementation of attribute certificate functionality, which has been defined in the fourth edition of the ITU-T X509 Standard. Attribute certificates cannot be stored in default Sun's keystore because they are parsed according to PKC format before they are stored. Therefore, they should be placed in an LDAP server. Attribute Certificates could be pulled and pushed to an LDAP server using JNDI API.

DDJ

Terms of Service | Privacy Statement | Copyright © 2024 UBM Tech, All rights reserved.