package org.bouncycastle.crypto.tls;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Vector;

/*
 * RFC 3546 3.3
 */
public class CertificateURL
{
    protected short type;
    protected Vector urlAndHashList;

    
Params:
/** * @param type * see {@link CertChainType} for valid constants. * @param urlAndHashList * a {@link Vector} of {@link URLAndHash}. */
public CertificateURL(short type, Vector urlAndHashList) { if (!CertChainType.isValid(type)) { throw new IllegalArgumentException("'type' is not a valid CertChainType value"); } if (urlAndHashList == null || urlAndHashList.isEmpty()) { throw new IllegalArgumentException("'urlAndHashList' must have length > 0"); } this.type = type; this.urlAndHashList = urlAndHashList; }
Returns:CertChainType
/** * @return {@link CertChainType} */
public short getType() { return type; }
Returns:a Vector of URLAndHash
/** * @return a {@link Vector} of {@link URLAndHash} */
public Vector getURLAndHashList() { return urlAndHashList; }
Encode this CertificateURL to an OutputStream.
Params:
Throws:
/** * Encode this {@link CertificateURL} to an {@link OutputStream}. * * @param output the {@link OutputStream} to encode to. * @throws IOException */
public void encode(OutputStream output) throws IOException { TlsUtils.writeUint8(this.type, output); ListBuffer16 buf = new ListBuffer16(); for (int i = 0; i < this.urlAndHashList.size(); ++i) { URLAndHash urlAndHash = (URLAndHash)this.urlAndHashList.elementAt(i); urlAndHash.encode(buf); } buf.encodeTo(output); }
Parse a CertificateURL from an InputStream.
Params:
Throws:
Returns:a CertificateURL object.
/** * Parse a {@link CertificateURL} from an {@link InputStream}. * * @param context * the {@link TlsContext} of the current connection. * @param input * the {@link InputStream} to parse from. * @return a {@link CertificateURL} object. * @throws IOException */
public static CertificateURL parse(TlsContext context, InputStream input) throws IOException { short type = TlsUtils.readUint8(input); if (!CertChainType.isValid(type)) { throw new TlsFatalAlert(AlertDescription.decode_error); } int totalLength = TlsUtils.readUint16(input); if (totalLength < 1) { throw new TlsFatalAlert(AlertDescription.decode_error); } byte[] urlAndHashListData = TlsUtils.readFully(totalLength, input); ByteArrayInputStream buf = new ByteArrayInputStream(urlAndHashListData); Vector url_and_hash_list = new Vector(); while (buf.available() > 0) { URLAndHash url_and_hash = URLAndHash.parse(context, buf); url_and_hash_list.addElement(url_and_hash); } return new CertificateURL(type, url_and_hash_list); } // TODO Could be more generally useful class ListBuffer16 extends ByteArrayOutputStream { ListBuffer16() throws IOException { // Reserve space for length TlsUtils.writeUint16(0, this); } void encodeTo(OutputStream output) throws IOException { // Patch actual length back in int length = count - 2; TlsUtils.checkUint16(length); TlsUtils.writeUint16(length, buf, 0); output.write(buf, 0, count); buf = null; } } }