001package org.apache.commons.ssl.org.bouncycastle.asn1.x509;
002
003import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Object;
004import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Primitive;
005import org.apache.commons.ssl.org.bouncycastle.asn1.DERBitString;
006
007/**
008 * The KeyUsage object.
009 * <pre>
010 *    id-ce-keyUsage OBJECT IDENTIFIER ::=  { id-ce 15 }
011 *
012 *    KeyUsage ::= BIT STRING {
013 *         digitalSignature        (0),
014 *         nonRepudiation          (1),
015 *         keyEncipherment         (2),
016 *         dataEncipherment        (3),
017 *         keyAgreement            (4),
018 *         keyCertSign             (5),
019 *         cRLSign                 (6),
020 *         encipherOnly            (7),
021 *         decipherOnly            (8) }
022 * </pre>
023 */
024public class KeyUsage
025    extends ASN1Object
026{
027    public static final int        digitalSignature = (1 << 7); 
028    public static final int        nonRepudiation   = (1 << 6);
029    public static final int        keyEncipherment  = (1 << 5);
030    public static final int        dataEncipherment = (1 << 4);
031    public static final int        keyAgreement     = (1 << 3);
032    public static final int        keyCertSign      = (1 << 2);
033    public static final int        cRLSign          = (1 << 1);
034    public static final int        encipherOnly     = (1 << 0);
035    public static final int        decipherOnly     = (1 << 15);
036
037    private DERBitString bitString;
038
039    public static KeyUsage getInstance(Object obj)   // needs to be DERBitString for other VMs
040    {
041        if (obj instanceof KeyUsage)
042        {
043            return (KeyUsage)obj;
044        }
045        else if (obj != null)
046        {
047            return new KeyUsage(DERBitString.getInstance(obj));
048        }
049
050        return null;
051    }
052
053    public static KeyUsage fromExtensions(Extensions extensions)
054    {
055        return KeyUsage.getInstance(extensions.getExtensionParsedValue(Extension.keyUsage));
056    }
057
058    /**
059     * Basic constructor.
060     * 
061     * @param usage - the bitwise OR of the Key Usage flags giving the
062     * allowed uses for the key.
063     * e.g. (KeyUsage.keyEncipherment | KeyUsage.dataEncipherment)
064     */
065    public KeyUsage(
066        int usage)
067    {
068        this.bitString = new DERBitString(usage);
069    }
070
071    private KeyUsage(
072        DERBitString bitString)
073    {
074        this.bitString = bitString;
075    }
076
077    /**
078     * Return true if a given usage bit is set, false otherwise.
079     *
080     * @param usages combination of usage flags.
081     * @return true if all bits are set, false otherwise.
082     */
083    public boolean hasUsages(int usages)
084    {
085        return (bitString.intValue() & usages) == usages;
086    }
087
088    public byte[] getBytes()
089    {
090        return bitString.getBytes();
091    }
092
093    public int getPadBits()
094    {
095        return bitString.getPadBits();
096    }
097
098    public String toString()
099    {
100        byte[] data = bitString.getBytes();
101
102        if (data.length == 1)
103        {
104            return "KeyUsage: 0x" + Integer.toHexString(data[0] & 0xff);
105        }
106        return "KeyUsage: 0x" + Integer.toHexString((data[1] & 0xff) << 8 | (data[0] & 0xff));
107    }
108
109    public ASN1Primitive toASN1Primitive()
110    {
111        return bitString;
112    }
113}