001package org.apache.commons.ssl.org.bouncycastle.asn1.x509; 002 003import java.util.Enumeration; 004 005import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1EncodableVector; 006import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Object; 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.ASN1TaggedObject; 010import org.apache.commons.ssl.org.bouncycastle.asn1.DERSequence; 011import org.apache.commons.ssl.org.bouncycastle.asn1.DERTaggedObject; 012 013/** 014 * This class helps to support crossCerfificatePairs in a LDAP directory 015 * according RFC 2587 016 * 017 * <pre> 018 * crossCertificatePairATTRIBUTE::={ 019 * WITH SYNTAX CertificatePair 020 * EQUALITY MATCHING RULE certificatePairExactMatch 021 * ID joint-iso-ccitt(2) ds(5) attributeType(4) crossCertificatePair(40)} 022 * </pre> 023 * 024 * <blockquote> The forward elements of the crossCertificatePair attribute of a 025 * CA's directory entry shall be used to store all, except self-issued 026 * certificates issued to this CA. Optionally, the reverse elements of the 027 * crossCertificatePair attribute, of a CA's directory entry may contain a 028 * subset of certificates issued by this CA to other CAs. When both the forward 029 * and the reverse elements are present in a single attribute value, issuer name 030 * in one certificate shall match the subject name in the other and vice versa, 031 * and the subject public key in one certificate shall be capable of verifying 032 * the digital signature on the other certificate and vice versa. 033 * 034 * When a reverse element is present, the forward element value and the reverse 035 * element value need not be stored in the same attribute value; in other words, 036 * they can be stored in either a single attribute value or two attribute 037 * values. </blockquote> 038 * 039 * <pre> 040 * CertificatePair ::= SEQUENCE { 041 * forward [0] Certificate OPTIONAL, 042 * reverse [1] Certificate OPTIONAL, 043 * -- at least one of the pair shall be present -- } 044 * </pre> 045 */ 046public class CertificatePair 047 extends ASN1Object 048{ 049 private Certificate forward; 050 051 private Certificate reverse; 052 053 public static CertificatePair getInstance(Object obj) 054 { 055 if (obj == null || obj instanceof CertificatePair) 056 { 057 return (CertificatePair)obj; 058 } 059 060 if (obj instanceof ASN1Sequence) 061 { 062 return new CertificatePair((ASN1Sequence)obj); 063 } 064 065 throw new IllegalArgumentException("illegal object in getInstance: " 066 + obj.getClass().getName()); 067 } 068 069 /** 070 * Constructor from ASN1Sequence. 071 * <p> 072 * The sequence is of type CertificatePair: 073 * <pre> 074 * CertificatePair ::= SEQUENCE { 075 * forward [0] Certificate OPTIONAL, 076 * reverse [1] Certificate OPTIONAL, 077 * -- at least one of the pair shall be present -- } 078 * </pre> 079 * </p> 080 * @param seq The ASN.1 sequence. 081 */ 082 private CertificatePair(ASN1Sequence seq) 083 { 084 if (seq.size() != 1 && seq.size() != 2) 085 { 086 throw new IllegalArgumentException("Bad sequence size: " 087 + seq.size()); 088 } 089 090 Enumeration e = seq.getObjects(); 091 092 while (e.hasMoreElements()) 093 { 094 ASN1TaggedObject o = ASN1TaggedObject.getInstance(e.nextElement()); 095 if (o.getTagNo() == 0) 096 { 097 forward = Certificate.getInstance(o, true); 098 } 099 else if (o.getTagNo() == 1) 100 { 101 reverse = Certificate.getInstance(o, true); 102 } 103 else 104 { 105 throw new IllegalArgumentException("Bad tag number: " 106 + o.getTagNo()); 107 } 108 } 109 } 110 111 /** 112 * Constructor from a given details. 113 * 114 * @param forward Certificates issued to this CA. 115 * @param reverse Certificates issued by this CA to other CAs. 116 */ 117 public CertificatePair(Certificate forward, Certificate reverse) 118 { 119 this.forward = forward; 120 this.reverse = reverse; 121 } 122 123 /** 124 * Produce an object suitable for an ASN1OutputStream. 125 * <p> 126 * Returns: 127 * <pre> 128 * CertificatePair ::= SEQUENCE { 129 * forward [0] Certificate OPTIONAL, 130 * reverse [1] Certificate OPTIONAL, 131 * -- at least one of the pair shall be present -- } 132 * </pre> 133 * 134 * @return a ASN1Primitive 135 */ 136 public ASN1Primitive toASN1Primitive() 137 { 138 ASN1EncodableVector vec = new ASN1EncodableVector(); 139 140 if (forward != null) 141 { 142 vec.add(new DERTaggedObject(0, forward)); 143 } 144 if (reverse != null) 145 { 146 vec.add(new DERTaggedObject(1, reverse)); 147 } 148 149 return new DERSequence(vec); 150 } 151 152 /** 153 * @return Returns the forward. 154 */ 155 public Certificate getForward() 156 { 157 return forward; 158 } 159 160 /** 161 * @return Returns the reverse. 162 */ 163 public Certificate getReverse() 164 { 165 return reverse; 166 } 167}