Index: modules/security/src/main/java/common/org/apache/harmony/security/x509/AccessDescription.java =================================================================== --- modules/security/src/main/java/common/org/apache/harmony/security/x509/AccessDescription.java (revision 0) +++ modules/security/src/main/java/common/org/apache/harmony/security/x509/AccessDescription.java (revision 0) @@ -0,0 +1,123 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.harmony.security.x509; + +import org.apache.harmony.security.asn1.ASN1Oid; +import org.apache.harmony.security.asn1.ASN1Sequence; +import org.apache.harmony.security.asn1.ASN1Type; +import org.apache.harmony.security.asn1.BerInputStream; +import org.apache.harmony.security.asn1.ObjectIdentifier; + +/** + * The class incapsulates the ASN.1 DER encoding/decoding work + * with the AccessDescription which is a part of X.509 framework + * (as specified in RFC 3280 - + * Internet X.509 Public Key Infrastructure. + * Certificate and Certificate Revocation List (CRL) Profile. + * http://www.ietf.org/rfc/rfc3280.txt): + * + * AccessDescription ::= SEQUENCE { + * accessMethod OBJECT IDENTIFIER, + * accessLocation GeneralName } + * + */ +public class AccessDescription { + + // the value of access method + private final String accessMethod; + + // the value of accessLocation + private final GeneralName accessLocation; + + private byte [] encoding; + + public AccessDescription(String accessMethod, GeneralName accessLocation) { + this.accessMethod = accessMethod; + this.accessLocation = accessLocation; + } + + private AccessDescription(String accessMethod, GeneralName accessLocation, + byte[] encoding) { + this.accessMethod = accessMethod; + this.accessLocation = accessLocation; + this.encoding = encoding; + } + + /** + * Returns ASN.1 encoded form of this X.509 AccessDescription. + * @return a byte array containing ASN.1 encoded form. + */ + public byte[] getEncoded() { + if (encoding == null) { + encoding = ASN1.encode(this); + } + return encoding; + } + + public String toString() { + StringBuffer res = new StringBuffer(); + res.append("\n-- AccessDescription:"); //$NON-NLS-1$ + res.append("\naccessMethod: "); //$NON-NLS-1$ + res.append(accessMethod); + res.append("\naccessLocation: "); //$NON-NLS-1$ + res.append(accessLocation); + res.append("\n-- AccessDescription END\n"); //$NON-NLS-1$ + return res.toString(); + } + + /** + * @return Returns the accessLocation. + */ + public GeneralName getAccessLocation() { + return accessLocation; + } + + /** + * @return Returns the accessMethod. + */ + public String getAccessMethod() { + return accessMethod; + } + + /** + * Custom AccessDescription DER encoder/decoder + */ + public static final ASN1Sequence ASN1 = new ASN1Sequence(new ASN1Type[] { + ASN1Oid.getInstance(), + GeneralName.ASN1 }) { + + protected Object getDecodedObject(BerInputStream in) { + Object[] values = (Object[]) in.content; + return new AccessDescription( + ObjectIdentifier.toString((int[]) values[0]), + (GeneralName) values[1], in.getEncoded()); + } + + protected void getValues(Object object, Object[] values) { + + AccessDescription ad = (AccessDescription) object; + + values[0] = ObjectIdentifier.toIntArray(ad.accessMethod); + values[1] = ad.accessLocation; + } + }; + +} + Index: modules/security/src/main/java/common/org/apache/harmony/security/x509/Extension.java =================================================================== --- modules/security/src/main/java/common/org/apache/harmony/security/x509/Extension.java (revision 474690) +++ modules/security/src/main/java/common/org/apache/harmony/security/x509/Extension.java (working copy) @@ -315,6 +315,8 @@ extnValueObject = new CRLNumber(extnValue); } else if (oidEquals(extnID, ISSUING_DISTR_POINTS)) { extnValueObject = IssuingDistributionPoint.decode(extnValue); + } else if (oidEquals(extnID, AUTHORITY_INFO_ACCESS)) { + extnValueObject = InfoAccessSyntax.decode(extnValue); } } Index: modules/security/src/main/java/common/org/apache/harmony/security/x509/InfoAccessSyntax.java =================================================================== --- modules/security/src/main/java/common/org/apache/harmony/security/x509/InfoAccessSyntax.java (revision 0) +++ modules/security/src/main/java/common/org/apache/harmony/security/x509/InfoAccessSyntax.java (revision 0) @@ -0,0 +1,137 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.harmony.security.x509; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import org.apache.harmony.security.asn1.ASN1SequenceOf; +import org.apache.harmony.security.asn1.ASN1Type; +import org.apache.harmony.security.asn1.BerInputStream; +import org.apache.harmony.security.internal.nls.Messages; + +/** + * The class incapsulates the ASN.1 DER encoding/decoding work + * with the SubjectInfoAccessSyntax and SubjectInfoAccessSyntax + * which are a part of X.509 framework + * (as specified in RFC 3280 - + * Internet X.509 Public Key Infrastructure. + * Certificate and Certificate Revocation List (CRL) Profile. + * http://www.ietf.org/rfc/rfc3280.txt): + * + * SubjectInfoAccessSyntax ::= + * SEQUENCE SIZE (1..MAX) OF AccessDescriptions + + * AuthorityInfoAccessSyntax ::= + * SEQUENCE SIZE (1..MAX) OF AccessDescriptions + * + * AccessDescription ::= SEQUENCE { + * accessMethod OBJECT IDENTIFIER, + * accessLocation GeneralName } + * + */ +public class InfoAccessSyntax extends ExtensionValue { + + private final List accessDescriptions; + + public InfoAccessSyntax(List accessDescriptions) throws IOException { + this(accessDescriptions, null); + } + + private InfoAccessSyntax(List accessDescriptions, byte[] encoding) + throws IOException { + if (accessDescriptions == null || accessDescriptions.isEmpty()) { + // "AccessDescriptions list is null or empty" + throw new IOException(Messages.getString("security.1A3")); //$NON-NLS-1$ + } + this.accessDescriptions = accessDescriptions; + this.encoding = encoding; + } + + public List getAccessDescriptions() { + return new ArrayList(accessDescriptions); + } + + /** + * Returns ASN.1 encoded form of this X.509 InfoAccessSyntax. + * @return a byte array containing ASN.1 encoded form. + */ + public byte[] getEncoded() { + if (encoding == null) { + encoding = ASN1.encode(this); + } + return encoding; + } + + public static InfoAccessSyntax decode(byte[] encoding) throws IOException { + return ((InfoAccessSyntax) ASN1.decode(encoding)); + } + + public String toString() { + StringBuffer res = new StringBuffer(); + res.append("\n---- InfoAccessSyntax:"); //$NON-NLS-1$ + if (accessDescriptions != null) { + for (Iterator it = accessDescriptions.iterator(); it.hasNext();) { + res.append('\n'); + res.append(it.next()); + } + } + res.append("\n---- InfoAccessSyntax END\n"); //$NON-NLS-1$ + return res.toString(); + } + + /** + * Places the string representation of extension value + * into the StringBuffer object. + */ + public void dumpValue(StringBuffer buffer, String prefix) { + buffer.append(prefix).append("AccessDescriptions:\n"); //$NON-NLS-1$ + if (accessDescriptions == null || accessDescriptions.isEmpty()) { + buffer.append("NULL\n"); //$NON-NLS-1$ + } else { + Iterator itr = accessDescriptions.iterator(); + while (itr.hasNext()) { + buffer.append(itr.next().toString()); + } + } + } + + + /** + * ASN.1 DER X.509 AuthorityInfoAccessSyntax and SubjectInfoAccessSyntax + * encoder/decoder class. + */ + public static final ASN1Type ASN1 = new ASN1SequenceOf(AccessDescription.ASN1) { + + public Object getDecodedObject(BerInputStream in) throws IOException { + return new InfoAccessSyntax((List)in.content, in.getEncoded()); + } + + public Collection getValues(Object object) { + InfoAccessSyntax aias = (InfoAccessSyntax) object; + return aias.accessDescriptions; + } + }; + +} +