001package org.apache.commons.ssl.org.bouncycastle.asn1.cms; 002 003import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Encodable; 004import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1EncodableVector; 005import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Object; 006import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1ObjectIdentifier; 007import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Primitive; 008import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Sequence; 009import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Set; 010import org.apache.commons.ssl.org.bouncycastle.asn1.DERSequence; 011 012/** 013 * <a href="http://tools.ietf.org/html/rfc5652#page-14">RFC 5652</a>: 014 * Attribute is a pair of OID (as type identifier) + set of values. 015 * <p> 016 * <pre> 017 * Attribute ::= SEQUENCE { 018 * attrType OBJECT IDENTIFIER, 019 * attrValues SET OF AttributeValue 020 * } 021 * 022 * AttributeValue ::= ANY 023 * </pre> 024 * <p> 025 * General rule on values is that same AttributeValue must not be included 026 * multiple times into the set. That is, if the value is a SET OF INTEGERs, 027 * then having same value repeated is wrong: (1, 1), but different values is OK: (1, 2). 028 * Normally the AttributeValue syntaxes are more complicated than that. 029 * <p> 030 * General rule of Attribute usage is that the {@link Attributes} containers 031 * must not have multiple Attribute:s with same attrType (OID) there. 032 */ 033public class Attribute 034 extends ASN1Object 035{ 036 private ASN1ObjectIdentifier attrType; 037 private ASN1Set attrValues; 038 039 /** 040 * Return an Attribute object from the given object. 041 * <p> 042 * Accepted inputs: 043 * <ul> 044 * <li> null → null 045 * <li> {@link Attribute} object 046 * <li> {@link org.bouncycastle.asn1.ASN1Sequence#getInstance(java.lang.Object) ASN1Sequence} input formats with Attribute structure inside 047 * </ul> 048 * 049 * @param o the object we want converted. 050 * @exception IllegalArgumentException if the object cannot be converted. 051 */ 052 public static Attribute getInstance( 053 Object o) 054 { 055 if (o instanceof Attribute) 056 { 057 return (Attribute)o; 058 } 059 060 if (o != null) 061 { 062 return new Attribute(ASN1Sequence.getInstance(o)); 063 } 064 065 return null; 066 } 067 068 private Attribute( 069 ASN1Sequence seq) 070 { 071 attrType = (ASN1ObjectIdentifier)seq.getObjectAt(0); 072 attrValues = (ASN1Set)seq.getObjectAt(1); 073 } 074 075 public Attribute( 076 ASN1ObjectIdentifier attrType, 077 ASN1Set attrValues) 078 { 079 this.attrType = attrType; 080 this.attrValues = attrValues; 081 } 082 083 public ASN1ObjectIdentifier getAttrType() 084 { 085 return attrType; 086 } 087 088 public ASN1Set getAttrValues() 089 { 090 return attrValues; 091 } 092 093 public ASN1Encodable[] getAttributeValues() 094 { 095 return attrValues.toArray(); 096 } 097 098 /** 099 * Produce an object suitable for an ASN1OutputStream. 100 */ 101 public ASN1Primitive toASN1Primitive() 102 { 103 ASN1EncodableVector v = new ASN1EncodableVector(); 104 105 v.add(attrType); 106 v.add(attrValues); 107 108 return new DERSequence(v); 109 } 110}