*/
public Collection<? extends Certificate>
engineGenerateCertificates(InputStream inStream)
throws CertificateException {
if (inStream == null) {
throw new CertificateException(Messages.getString("security.153")); //$NON-NLS-1$
}
ArrayList result = new ArrayList();
try {
if (!inStream.markSupported()) {
// create the mark supporting wrapper
inStream = new RestoringInputStream(inStream);
}
// if it is PEM encoded form this array will contain the encoding
// so ((it is PEM) <-> (encoding != null))
byte[] encoding = null;
// The following by SEQUENCE ASN.1 tag, used for
// recognizing the data format
// (is it PKCS7 ContentInfo structure, X.509 Certificate, or
// unsupported encoding)
int second_asn1_tag = -1;
inStream.mark(1);
int ch;
while ((ch = inStream.read()) != -1) {
// check if it is PEM encoded form
if (ch == '-') { // beginning of PEM encoding ('-' char)
// decode PEM chunk and store its content (ASN.1 encoding)
encoding = decodePEM(inStream, FREE_BOUND_SUFFIX);
} else if (ch == 0x30) { // beginning of ASN.1 sequence (0x30)
encoding = null;
inStream.reset();
// prepare for data format determination
inStream.mark(CERT_CACHE_SEED_LENGTH);
} else { // unsupported data
if (result.size() == 0) {
throw new CertificateException(
Messages.getString("security.15F")); //$NON-NLS-1$
} else {
// it can be trailing user data,
// so keep it in the stream
inStream.reset();
return result;
}
}
// Check the data format
BerInputStream in = (encoding == null)
? new BerInputStream(inStream)
: new BerInputStream(encoding);
// read the next ASN.1 tag
second_asn1_tag = in.next(); // inStream position changed
if (encoding == null) {
// keep whole structure in the stream
inStream.reset();
}
// check if it is a TBSCertificate structure
if (second_asn1_tag != ASN1Constants.TAG_C_SEQUENCE) {
if (result.size() == 0) {
// there were not read X.509 Certificates, so
// break the cycle and check
// whether it is PKCS7 structure
break;
} else {
// it can be trailing user data,
// so return what we already read
return result;
}
} else {
if (encoding == null) {
result.add(getCertificate(inStream));
} else {
result.add(getCertificate(encoding));
}
}
// mark for the next iteration
inStream.mark(1);
}
if (result.size() != 0) {
// some Certificates have been read
return result;
} else if (ch == -1) {
throw new CertificateException(
Messages.getString("security.155")); //$NON-NLS-1$
}
// else: check if it is PKCS7
if (second_asn1_tag == ASN1Constants.TAG_OID) {
// it is PKCS7 ContentInfo structure, so decode it
ContentInfo info = (ContentInfo)
((encoding != null)
? ContentInfo.ASN1.decode(encoding)
: ContentInfo.ASN1.decode(inStream));
// retrieve SignedData
SignedData data = info.getSignedData();
if (data == null) {
throw new CertificateException(
Messages.getString("security.154")); //$NON-NLS-1$
}
List certs = data.getCertificates();
if (certs != null) {
for (int i = 0; i < certs.size(); i++) {
result.add(new X509CertImpl(
(org.apache.harmony.security.x509.Certificate)
certs.get(i)));
}
}
return result;
}
// else: Unknown data format
throw new CertificateException(
Messages.getString("security.15F")); //$NON-NLS-1$
} catch (IOException e) {
throw new CertificateException(e);
}
}