use of org.bouncycastle.asn1.DERUTF8String in project xipki by xipki.
the class X509Ca method createGrantedCertTemplate.
private GrantedCertTemplate createGrantedCertTemplate(CertTemplateData certTemplate, RequestorInfo requestor, boolean keyUpdate) throws OperationException {
ParamUtil.requireNonNull("certTemplate", certTemplate);
if (caInfo.getRevocationInfo() != null) {
throw new OperationException(ErrorCode.NOT_PERMITTED, "CA is revoked");
}
IdentifiedX509Certprofile certprofile = getX509Certprofile(certTemplate.getCertprofileName());
if (certprofile == null) {
throw new OperationException(ErrorCode.UNKNOWN_CERT_PROFILE, "unknown cert profile " + certTemplate.getCertprofileName());
}
ConcurrentContentSigner signer = caInfo.getSigner(certprofile.getSignatureAlgorithms());
if (signer == null) {
throw new OperationException(ErrorCode.SYSTEM_FAILURE, "CA does not support any signature algorithm restricted by the cert profile");
}
final NameId certprofileIdent = certprofile.getIdent();
if (certprofile.getVersion() != X509CertVersion.v3) {
throw new OperationException(ErrorCode.SYSTEM_FAILURE, "unknown cert version " + certprofile.getVersion());
}
if (certprofile.isOnlyForRa()) {
if (requestor == null || !requestor.isRa()) {
throw new OperationException(ErrorCode.NOT_PERMITTED, "profile " + certprofileIdent + " not applied to non-RA");
}
}
X500Name requestedSubject = removeEmptyRdns(certTemplate.getSubject());
if (!certprofile.isSerialNumberInReqPermitted()) {
RDN[] rdns = requestedSubject.getRDNs(ObjectIdentifiers.DN_SN);
if (rdns != null && rdns.length > 0) {
throw new OperationException(ErrorCode.BAD_CERT_TEMPLATE, "subjectDN SerialNumber in request is not permitted");
}
}
Date now = new Date();
Date reqNotBefore;
if (certTemplate.getNotBefore() != null && certTemplate.getNotBefore().after(now)) {
reqNotBefore = certTemplate.getNotBefore();
} else {
reqNotBefore = now;
}
Date grantedNotBefore = certprofile.getNotBefore(reqNotBefore);
// notBefore in the past is not permitted
if (grantedNotBefore.before(now)) {
grantedNotBefore = now;
}
if (certprofile.hasMidnightNotBefore()) {
grantedNotBefore = setToMidnight(grantedNotBefore, certprofile.getTimezone());
}
if (grantedNotBefore.before(caInfo.getNotBefore())) {
grantedNotBefore = caInfo.getNotBefore();
if (certprofile.hasMidnightNotBefore()) {
grantedNotBefore = setToMidnight(grantedNotBefore, certprofile.getTimezone());
}
}
long time = caInfo.getNoNewCertificateAfter();
if (grantedNotBefore.getTime() > time) {
throw new OperationException(ErrorCode.NOT_PERMITTED, "CA is not permitted to issue certifate after " + new Date(time));
}
SubjectPublicKeyInfo grantedPublicKeyInfo;
try {
grantedPublicKeyInfo = X509Util.toRfc3279Style(certTemplate.getPublicKeyInfo());
} catch (InvalidKeySpecException ex) {
LogUtil.warn(LOG, ex, "invalid SubjectPublicKeyInfo");
throw new OperationException(ErrorCode.BAD_CERT_TEMPLATE, "invalid SubjectPublicKeyInfo");
}
// public key
try {
grantedPublicKeyInfo = certprofile.checkPublicKey(grantedPublicKeyInfo);
} catch (BadCertTemplateException ex) {
throw new OperationException(ErrorCode.BAD_CERT_TEMPLATE, ex);
}
// CHECK weak public key, like RSA key (ROCA)
if (grantedPublicKeyInfo.getAlgorithm().getAlgorithm().equals(PKCSObjectIdentifiers.rsaEncryption)) {
try {
ASN1Sequence seq = ASN1Sequence.getInstance(grantedPublicKeyInfo.getPublicKeyData().getOctets());
if (seq.size() != 2) {
throw new OperationException(ErrorCode.BAD_CERT_TEMPLATE, "invalid format of RSA public key");
}
BigInteger modulus = ASN1Integer.getInstance(seq.getObjectAt(0)).getPositiveValue();
if (RSABrokenKey.isAffected(modulus)) {
throw new OperationException(ErrorCode.BAD_CERT_TEMPLATE, "RSA public key is too weak");
}
} catch (IllegalArgumentException ex) {
throw new OperationException(ErrorCode.BAD_CERT_TEMPLATE, "invalid format of RSA public key");
}
}
Date gsmckFirstNotBefore = null;
if (certprofile.getspecialCertprofileBehavior() == SpecialX509CertprofileBehavior.gematik_gSMC_K) {
gsmckFirstNotBefore = grantedNotBefore;
RDN[] cnRdns = requestedSubject.getRDNs(ObjectIdentifiers.DN_CN);
if (cnRdns != null && cnRdns.length > 0) {
String requestedCn = X509Util.rdnValueToString(cnRdns[0].getFirst().getValue());
Long gsmckFirstNotBeforeInSecond = certstore.getNotBeforeOfFirstCertStartsWithCommonName(requestedCn, certprofileIdent);
if (gsmckFirstNotBeforeInSecond != null) {
gsmckFirstNotBefore = new Date(gsmckFirstNotBeforeInSecond * MS_PER_SECOND);
}
// append the commonName with '-' + yyyyMMdd
SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMdd");
dateF.setTimeZone(new SimpleTimeZone(0, "Z"));
String yyyyMMdd = dateF.format(gsmckFirstNotBefore);
String suffix = "-" + yyyyMMdd;
// append the -yyyyMMdd to the commonName
RDN[] rdns = requestedSubject.getRDNs();
for (int i = 0; i < rdns.length; i++) {
if (ObjectIdentifiers.DN_CN.equals(rdns[i].getFirst().getType())) {
rdns[i] = new RDN(ObjectIdentifiers.DN_CN, new DERUTF8String(requestedCn + suffix));
}
}
requestedSubject = new X500Name(rdns);
}
// end if
}
// end if
// subject
SubjectInfo subjectInfo;
try {
subjectInfo = certprofile.getSubject(requestedSubject);
} catch (CertprofileException ex) {
throw new OperationException(ErrorCode.SYSTEM_FAILURE, "exception in cert profile " + certprofileIdent);
} catch (BadCertTemplateException ex) {
throw new OperationException(ErrorCode.BAD_CERT_TEMPLATE, ex);
}
X500Name grantedSubject = subjectInfo.getGrantedSubject();
// make sure that empty subject is not permitted
ASN1ObjectIdentifier[] attrTypes = grantedSubject.getAttributeTypes();
if (attrTypes == null || attrTypes.length == 0) {
throw new OperationException(ErrorCode.BAD_CERT_TEMPLATE, "empty subject is not permitted");
}
// make sure that the grantedSubject does not equal the CA's subject
if (X509Util.canonicalizName(grantedSubject).equals(caInfo.getPublicCaInfo().getC14nSubject())) {
throw new OperationException(ErrorCode.ALREADY_ISSUED, "certificate with the same subject as CA is not allowed");
}
boolean duplicateKeyPermitted = caInfo.isDuplicateKeyPermitted();
if (duplicateKeyPermitted && !certprofile.isDuplicateKeyPermitted()) {
duplicateKeyPermitted = false;
}
byte[] subjectPublicKeyData = grantedPublicKeyInfo.getPublicKeyData().getBytes();
long fpPublicKey = FpIdCalculator.hash(subjectPublicKeyData);
if (keyUpdate) {
CertStatus certStatus = certstore.getCertStatusForSubject(caIdent, grantedSubject);
if (certStatus == CertStatus.REVOKED) {
throw new OperationException(ErrorCode.CERT_REVOKED);
} else if (certStatus == CertStatus.UNKNOWN) {
throw new OperationException(ErrorCode.UNKNOWN_CERT);
}
} else {
if (!duplicateKeyPermitted) {
if (certstore.isCertForKeyIssued(caIdent, fpPublicKey)) {
throw new OperationException(ErrorCode.ALREADY_ISSUED, "certificate for the given public key already issued");
}
}
// duplicateSubject check will be processed later
}
// end if(keyUpdate)
StringBuilder msgBuilder = new StringBuilder();
if (subjectInfo.getWarning() != null) {
msgBuilder.append(", ").append(subjectInfo.getWarning());
}
CertValidity validity = certprofile.getValidity();
if (validity == null) {
validity = caInfo.getMaxValidity();
} else if (validity.compareTo(caInfo.getMaxValidity()) > 0) {
validity = caInfo.getMaxValidity();
}
Date maxNotAfter = validity.add(grantedNotBefore);
if (maxNotAfter.getTime() > MAX_CERT_TIME_MS) {
maxNotAfter = new Date(MAX_CERT_TIME_MS);
}
// CHECKSTYLE:SKIP
Date origMaxNotAfter = maxNotAfter;
if (certprofile.getspecialCertprofileBehavior() == SpecialX509CertprofileBehavior.gematik_gSMC_K) {
String str = certprofile.setParameter(SpecialX509CertprofileBehavior.PARAMETER_MAXLIFTIME);
long maxLifetimeInDays = Long.parseLong(str);
Date maxLifetime = new Date(gsmckFirstNotBefore.getTime() + maxLifetimeInDays * DAY_IN_MS - MS_PER_SECOND);
if (maxNotAfter.after(maxLifetime)) {
maxNotAfter = maxLifetime;
}
}
Date grantedNotAfter = certTemplate.getNotAfter();
if (grantedNotAfter != null) {
if (grantedNotAfter.after(maxNotAfter)) {
grantedNotAfter = maxNotAfter;
msgBuilder.append(", notAfter modified");
}
} else {
grantedNotAfter = maxNotAfter;
}
if (grantedNotAfter.after(caInfo.getNotAfter())) {
ValidityMode mode = caInfo.getValidityMode();
if (mode == ValidityMode.CUTOFF) {
grantedNotAfter = caInfo.getNotAfter();
} else if (mode == ValidityMode.STRICT) {
throw new OperationException(ErrorCode.NOT_PERMITTED, "notAfter outside of CA's validity is not permitted");
} else if (mode == ValidityMode.LAX) {
// permitted
} else {
throw new RuntimeException("should not reach here, unknown CA ValidityMode " + mode);
}
// end if (mode)
}
if (certprofile.hasMidnightNotBefore() && !maxNotAfter.equals(origMaxNotAfter)) {
Calendar cal = Calendar.getInstance(certprofile.getTimezone());
cal.setTime(new Date(grantedNotAfter.getTime() - DAY_IN_MS));
cal.set(Calendar.HOUR_OF_DAY, 23);
cal.set(Calendar.MINUTE, 59);
cal.set(Calendar.SECOND, 59);
cal.set(Calendar.MILLISECOND, 0);
grantedNotAfter = cal.getTime();
}
String warning = null;
if (msgBuilder.length() > 2) {
warning = msgBuilder.substring(2);
}
GrantedCertTemplate gct = new GrantedCertTemplate(certTemplate.getExtensions(), certprofile, grantedNotBefore, grantedNotAfter, requestedSubject, grantedPublicKeyInfo, fpPublicKey, subjectPublicKeyData, signer, warning);
gct.setGrantedSubject(grantedSubject);
return gct;
}
use of org.bouncycastle.asn1.DERUTF8String in project xipki by xipki.
the class ExtensionsChecker method createGeneralName.
private static GeneralName createGeneralName(GeneralName reqName, Set<GeneralNameMode> modes) throws BadCertTemplateException {
int tag = reqName.getTagNo();
GeneralNameMode mode = null;
if (modes != null) {
for (GeneralNameMode m : modes) {
if (m.getTag().getTag() == tag) {
mode = m;
break;
}
}
if (mode == null) {
throw new BadCertTemplateException("generalName tag " + tag + " is not allowed");
}
}
switch(tag) {
case GeneralName.rfc822Name:
case GeneralName.dNSName:
case GeneralName.uniformResourceIdentifier:
case GeneralName.iPAddress:
case GeneralName.registeredID:
case GeneralName.directoryName:
return new GeneralName(tag, reqName.getName());
case GeneralName.otherName:
ASN1Sequence reqSeq = ASN1Sequence.getInstance(reqName.getName());
ASN1ObjectIdentifier type = ASN1ObjectIdentifier.getInstance(reqSeq.getObjectAt(0));
if (mode != null && !mode.getAllowedTypes().contains(type)) {
throw new BadCertTemplateException("otherName.type " + type.getId() + " is not allowed");
}
ASN1Encodable value = ASN1TaggedObject.getInstance(reqSeq.getObjectAt(1)).getObject();
String text;
if (!(value instanceof ASN1String)) {
throw new BadCertTemplateException("otherName.value is not a String");
} else {
text = ((ASN1String) value).getString();
}
ASN1EncodableVector vector = new ASN1EncodableVector();
vector.add(type);
vector.add(new DERTaggedObject(true, 0, new DERUTF8String(text)));
DERSequence seq = new DERSequence(vector);
return new GeneralName(GeneralName.otherName, seq);
case GeneralName.ediPartyName:
reqSeq = ASN1Sequence.getInstance(reqName.getName());
int size = reqSeq.size();
String nameAssigner = null;
int idx = 0;
if (size > 1) {
DirectoryString ds = DirectoryString.getInstance(ASN1TaggedObject.getInstance(reqSeq.getObjectAt(idx++)).getObject());
nameAssigner = ds.getString();
}
DirectoryString ds = DirectoryString.getInstance(ASN1TaggedObject.getInstance(reqSeq.getObjectAt(idx++)).getObject());
String partyName = ds.getString();
vector = new ASN1EncodableVector();
if (nameAssigner != null) {
vector.add(new DERTaggedObject(false, 0, new DirectoryString(nameAssigner)));
}
vector.add(new DERTaggedObject(false, 1, new DirectoryString(partyName)));
seq = new DERSequence(vector);
return new GeneralName(GeneralName.ediPartyName, seq);
default:
throw new RuntimeException("should not reach here, unknown GeneralName tag " + tag);
}
// end switch
}
use of org.bouncycastle.asn1.DERUTF8String in project xipki by xipki.
the class ExtensionsChecker method checkDirectoryString.
private void checkDirectoryString(ASN1ObjectIdentifier extType, QaDirectoryString conf, StringBuilder failureMsg, byte[] extensionValue, Extensions requestedExtensions, ExtensionControl extControl) {
if (conf == null) {
byte[] expected = getExpectedExtValue(extType, requestedExtensions, extControl);
if (!Arrays.equals(expected, extensionValue)) {
addViolation(failureMsg, "extension values", hex(extensionValue), (expected == null) ? "not present" : hex(expected));
}
return;
}
ASN1Primitive asn1;
try {
asn1 = ASN1Primitive.fromByteArray(extensionValue);
} catch (IOException ex) {
failureMsg.append("invalid syntax of extension value; ");
return;
}
boolean correctStringType;
switch(conf.getType()) {
case bmpString:
correctStringType = (asn1 instanceof DERBMPString);
break;
case printableString:
correctStringType = (asn1 instanceof DERPrintableString);
break;
case teletexString:
correctStringType = (asn1 instanceof DERT61String);
break;
case utf8String:
correctStringType = (asn1 instanceof DERUTF8String);
break;
default:
throw new RuntimeException("should not reach here, unknown DirectoryStringType " + conf.getType());
}
if (!correctStringType) {
failureMsg.append("extension value is not of type DirectoryString.").append(conf.getText()).append("; ");
return;
}
String extTextValue = ((ASN1String) asn1).getString();
if (!conf.getText().equals(extTextValue)) {
addViolation(failureMsg, "content", extTextValue, conf.getText());
}
}
use of org.bouncycastle.asn1.DERUTF8String in project xipki by xipki.
the class P12ComplexCsrGenCmd method getSubject.
@Override
protected X500Name getSubject(String subject) {
X500Name name = new X500Name(subject);
List<RDN> list = new LinkedList<>();
RDN[] rs = name.getRDNs();
for (RDN m : rs) {
list.add(m);
}
ASN1ObjectIdentifier id;
// dateOfBirth
if (complexSubject.booleanValue()) {
id = ObjectIdentifiers.DN_DATE_OF_BIRTH;
RDN[] rdns = name.getRDNs(id);
if (rdns == null || rdns.length == 0) {
ASN1Encodable atvValue = new DERGeneralizedTime("19950102120000Z");
RDN rdn = new RDN(id, atvValue);
list.add(rdn);
}
}
// postalAddress
if (complexSubject.booleanValue()) {
id = ObjectIdentifiers.DN_POSTAL_ADDRESS;
RDN[] rdns = name.getRDNs(id);
if (rdns == null || rdns.length == 0) {
ASN1EncodableVector vec = new ASN1EncodableVector();
vec.add(new DERUTF8String("my street 1"));
vec.add(new DERUTF8String("12345 Germany"));
ASN1Sequence atvValue = new DERSequence(vec);
RDN rdn = new RDN(id, atvValue);
list.add(rdn);
}
}
// DN_UNIQUE_IDENTIFIER
id = ObjectIdentifiers.DN_UNIQUE_IDENTIFIER;
RDN[] rdns = name.getRDNs(id);
if (rdns == null || rdns.length == 0) {
DERUTF8String atvValue = new DERUTF8String("abc-def-ghi");
RDN rdn = new RDN(id, atvValue);
list.add(rdn);
}
return new X500Name(list.toArray(new RDN[0]));
}
use of org.bouncycastle.asn1.DERUTF8String in project keepass2android by PhilippC.
the class ASN1Dump method _dumpAsString.
/**
* dump a DER object as a formatted string with indentation
*
* @param obj the DERObject to be dumped out.
*/
static void _dumpAsString(String indent, boolean verbose, DERObject obj, StringBuffer buf) {
String nl = System.getProperty("line.separator");
if (obj instanceof ASN1Sequence) {
Enumeration e = ((ASN1Sequence) obj).getObjects();
String tab = indent + TAB;
buf.append(indent);
if (obj instanceof BERConstructedSequence) {
buf.append("BER ConstructedSequence");
} else if (obj instanceof DERConstructedSequence) {
buf.append("DER ConstructedSequence");
} else if (obj instanceof BERSequence) {
buf.append("BER Sequence");
} else if (obj instanceof DERSequence) {
buf.append("DER Sequence");
} else {
buf.append("Sequence");
}
buf.append(nl);
while (e.hasMoreElements()) {
Object o = e.nextElement();
if (o == null || o.equals(new DERNull())) {
buf.append(tab);
buf.append("NULL");
buf.append(nl);
} else if (o instanceof DERObject) {
_dumpAsString(tab, verbose, (DERObject) o, buf);
} else {
_dumpAsString(tab, verbose, ((DEREncodable) o).getDERObject(), buf);
}
}
} else if (obj instanceof DERTaggedObject) {
String tab = indent + TAB;
buf.append(indent);
if (obj instanceof BERTaggedObject) {
buf.append("BER Tagged [");
} else {
buf.append("Tagged [");
}
DERTaggedObject o = (DERTaggedObject) obj;
buf.append(Integer.toString(o.getTagNo()));
buf.append(']');
if (!o.isExplicit()) {
buf.append(" IMPLICIT ");
}
buf.append(nl);
if (o.isEmpty()) {
buf.append(tab);
buf.append("EMPTY");
buf.append(nl);
} else {
_dumpAsString(tab, verbose, o.getObject(), buf);
}
} else if (obj instanceof DERConstructedSet) {
Enumeration e = ((ASN1Set) obj).getObjects();
String tab = indent + TAB;
buf.append(indent);
buf.append("ConstructedSet");
buf.append(nl);
while (e.hasMoreElements()) {
Object o = e.nextElement();
if (o == null) {
buf.append(tab);
buf.append("NULL");
buf.append(nl);
} else if (o instanceof DERObject) {
_dumpAsString(tab, verbose, (DERObject) o, buf);
} else {
_dumpAsString(tab, verbose, ((DEREncodable) o).getDERObject(), buf);
}
}
} else if (obj instanceof BERSet) {
Enumeration e = ((ASN1Set) obj).getObjects();
String tab = indent + TAB;
buf.append(indent);
buf.append("BER Set");
buf.append(nl);
while (e.hasMoreElements()) {
Object o = e.nextElement();
if (o == null) {
buf.append(tab);
buf.append("NULL");
buf.append(nl);
} else if (o instanceof DERObject) {
_dumpAsString(tab, verbose, (DERObject) o, buf);
} else {
_dumpAsString(tab, verbose, ((DEREncodable) o).getDERObject(), buf);
}
}
} else if (obj instanceof DERSet) {
Enumeration e = ((ASN1Set) obj).getObjects();
String tab = indent + TAB;
buf.append(indent);
buf.append("DER Set");
buf.append(nl);
while (e.hasMoreElements()) {
Object o = e.nextElement();
if (o == null) {
buf.append(tab);
buf.append("NULL");
buf.append(nl);
} else if (o instanceof DERObject) {
_dumpAsString(tab, verbose, (DERObject) o, buf);
} else {
_dumpAsString(tab, verbose, ((DEREncodable) o).getDERObject(), buf);
}
}
} else if (obj instanceof DERObjectIdentifier) {
buf.append(indent + "ObjectIdentifier(" + ((DERObjectIdentifier) obj).getId() + ")" + nl);
} else if (obj instanceof DERBoolean) {
buf.append(indent + "Boolean(" + ((DERBoolean) obj).isTrue() + ")" + nl);
} else if (obj instanceof DERInteger) {
buf.append(indent + "Integer(" + ((DERInteger) obj).getValue() + ")" + nl);
} else if (obj instanceof BERConstructedOctetString) {
ASN1OctetString oct = (ASN1OctetString) obj;
buf.append(indent + "BER Constructed Octet String" + "[" + oct.getOctets().length + "] ");
if (verbose) {
buf.append(dumpBinaryDataAsString(indent, oct.getOctets()));
} else {
buf.append(nl);
}
} else if (obj instanceof DEROctetString) {
ASN1OctetString oct = (ASN1OctetString) obj;
buf.append(indent + "DER Octet String" + "[" + oct.getOctets().length + "] ");
if (verbose) {
buf.append(dumpBinaryDataAsString(indent, oct.getOctets()));
} else {
buf.append(nl);
}
} else if (obj instanceof DERBitString) {
DERBitString bt = (DERBitString) obj;
buf.append(indent + "DER Bit String" + "[" + bt.getBytes().length + ", " + bt.getPadBits() + "] ");
if (verbose) {
buf.append(dumpBinaryDataAsString(indent, bt.getBytes()));
} else {
buf.append(nl);
}
} else if (obj instanceof DERIA5String) {
buf.append(indent + "IA5String(" + ((DERIA5String) obj).getString() + ") " + nl);
} else if (obj instanceof DERUTF8String) {
buf.append(indent + "UTF8String(" + ((DERUTF8String) obj).getString() + ") " + nl);
} else if (obj instanceof DERPrintableString) {
buf.append(indent + "PrintableString(" + ((DERPrintableString) obj).getString() + ") " + nl);
} else if (obj instanceof DERVisibleString) {
buf.append(indent + "VisibleString(" + ((DERVisibleString) obj).getString() + ") " + nl);
} else if (obj instanceof DERBMPString) {
buf.append(indent + "BMPString(" + ((DERBMPString) obj).getString() + ") " + nl);
} else if (obj instanceof DERT61String) {
buf.append(indent + "T61String(" + ((DERT61String) obj).getString() + ") " + nl);
} else if (obj instanceof DERUTCTime) {
buf.append(indent + "UTCTime(" + ((DERUTCTime) obj).getTime() + ") " + nl);
} else if (obj instanceof DERGeneralizedTime) {
buf.append(indent + "GeneralizedTime(" + ((DERGeneralizedTime) obj).getTime() + ") " + nl);
} else if (obj instanceof DERUnknownTag) {
buf.append(indent + "Unknown " + Integer.toString(((DERUnknownTag) obj).getTag(), 16) + " " + new String(Hex.encode(((DERUnknownTag) obj).getData())) + nl);
} else if (obj instanceof BERApplicationSpecific) {
buf.append(outputApplicationSpecific("BER", indent, verbose, obj, nl));
} else if (obj instanceof DERApplicationSpecific) {
buf.append(outputApplicationSpecific("DER", indent, verbose, obj, nl));
} else if (obj instanceof DEREnumerated) {
DEREnumerated en = (DEREnumerated) obj;
buf.append(indent + "DER Enumerated(" + en.getValue() + ")" + nl);
} else if (obj instanceof DERExternal) {
DERExternal ext = (DERExternal) obj;
buf.append(indent + "External " + nl);
String tab = indent + TAB;
if (ext.getDirectReference() != null) {
buf.append(tab + "Direct Reference: " + ext.getDirectReference().getId() + nl);
}
if (ext.getIndirectReference() != null) {
buf.append(tab + "Indirect Reference: " + ext.getIndirectReference().toString() + nl);
}
if (ext.getDataValueDescriptor() != null) {
_dumpAsString(tab, verbose, ext.getDataValueDescriptor(), buf);
}
buf.append(tab + "Encoding: " + ext.getEncoding() + nl);
_dumpAsString(tab, verbose, ext.getExternalContent(), buf);
} else {
buf.append(indent + obj.toString() + nl);
}
}
Aggregations