Example usage for org.bouncycastle.asn1.cmp InfoTypeAndValue getInfoType

List of usage examples for org.bouncycastle.asn1.cmp InfoTypeAndValue getInfoType

Introduction

In this page you can find the example usage for org.bouncycastle.asn1.cmp InfoTypeAndValue getInfoType.

Prototype

public ASN1ObjectIdentifier getInfoType() 

Source Link

Usage

From source file:org.xipki.ca.client.impl.CmpRequestor.java

License:Open Source License

private ASN1Encodable extractGeneralRepContent(final PKIResponse response, final String exepectedType,
        final boolean requireProtectionCheck) throws CmpRequestorException, PKIErrorException {
    if (requireProtectionCheck) {
        checkProtection(response);//from   ww w. j  ava 2s.c  o m
    }

    PKIBody respBody = response.getPkiMessage().getBody();
    int bodyType = respBody.getType();

    if (PKIBody.TYPE_ERROR == bodyType) {
        ErrorMsgContent content = (ErrorMsgContent) respBody.getContent();
        throw new CmpRequestorException(SecurityUtil.formatPKIStatusInfo(content.getPKIStatusInfo()));
    } else if (PKIBody.TYPE_GEN_REP != bodyType) {
        throw new CmpRequestorException("unknown PKI body type " + bodyType + " instead the exceptected ["
                + PKIBody.TYPE_GEN_REP + ", " + PKIBody.TYPE_ERROR + "]");
    }

    GenRepContent genRep = (GenRepContent) respBody.getContent();

    InfoTypeAndValue[] itvs = genRep.toInfoTypeAndValueArray();
    InfoTypeAndValue itv = null;
    if (itvs != null && itvs.length > 0) {
        for (InfoTypeAndValue _itv : itvs) {
            if (exepectedType.equals(_itv.getInfoType().getId())) {
                itv = _itv;
                break;
            }
        }
    }
    if (itv == null) {
        throw new CmpRequestorException("the response does not contain InfoTypeAndValue " + exepectedType);
    }

    return itv.getInfoValue();
}

From source file:org.xipki.ca.client.impl.CmpRequestor.java

License:Open Source License

protected PKIHeader buildPKIHeader(final boolean addImplictConfirm, final ASN1OctetString tid,
        final CmpUtf8Pairs utf8Pairs, final InfoTypeAndValue... additionalGeneralInfos) {
    if (additionalGeneralInfos != null) {
        for (InfoTypeAndValue itv : additionalGeneralInfos) {
            ASN1ObjectIdentifier type = itv.getInfoType();
            if (CMPObjectIdentifiers.it_implicitConfirm.equals(type)) {
                throw new IllegalArgumentException(
                        "" + "additionGeneralInfos contains unpermitted ITV implicitConfirm");
            }/*from  ww w. j ava2s. co m*/

            if (CMPObjectIdentifiers.regInfo_utf8Pairs.equals(type)) {
                throw new IllegalArgumentException(
                        "" + "additionGeneralInfos contains unpermitted ITV utf8Pairs");
            }
        }
    }

    PKIHeaderBuilder hBuilder = new PKIHeaderBuilder(PKIHeader.CMP_2000, sender,
            recipient != null ? recipient : DUMMY_RECIPIENT);
    hBuilder.setMessageTime(new ASN1GeneralizedTime(new Date()));

    ASN1OctetString _tid;
    if (tid == null) {
        _tid = new DEROctetString(randomTransactionId());
    } else {
        _tid = tid;
    }

    hBuilder.setTransactionID(_tid);

    List<InfoTypeAndValue> itvs = new ArrayList<>(2);
    if (addImplictConfirm) {
        itvs.add(CmpUtil.getImplictConfirmGeneralInfo());
    }

    if (utf8Pairs != null) {
        itvs.add(CmpUtil.buildInfoTypeAndValue(utf8Pairs));
    }

    if (additionalGeneralInfos != null) {
        for (InfoTypeAndValue itv : additionalGeneralInfos) {
            if (itv != null) {
                itvs.add(itv);
            }
        }
    }

    if (CollectionUtil.isNotEmpty(itvs)) {
        hBuilder.setGeneralInfo(itvs.toArray(new InfoTypeAndValue[0]));
    }

    return hBuilder.build();
}

From source file:org.xipki.ca.client.impl.X509CmpRequestor.java

License:Open Source License

private CRLResultType evaluateCRLResponse(final PKIResponse response, final Integer xipkiAction)
        throws CmpRequestorException, PKIErrorException {
    checkProtection(response);/*from   w  w w  .  j  av  a  2 s  .co m*/

    PKIBody respBody = response.getPkiMessage().getBody();
    int bodyType = respBody.getType();

    if (PKIBody.TYPE_ERROR == bodyType) {
        ErrorMsgContent content = (ErrorMsgContent) respBody.getContent();
        throw new PKIErrorException(content.getPKIStatusInfo());
    } else if (PKIBody.TYPE_GEN_REP != bodyType) {
        throw new CmpRequestorException("unknown PKI body type " + bodyType + " instead the exceptected ["
                + PKIBody.TYPE_GEN_REP + ", " + PKIBody.TYPE_ERROR + "]");
    }

    ASN1ObjectIdentifier expectedType = xipkiAction == null ? CMPObjectIdentifiers.it_currentCRL
            : ObjectIdentifiers.id_xipki_cmp;

    GenRepContent genRep = (GenRepContent) respBody.getContent();

    InfoTypeAndValue[] itvs = genRep.toInfoTypeAndValueArray();
    InfoTypeAndValue itv = null;
    if (itvs != null && itvs.length > 0) {
        for (InfoTypeAndValue m : itvs) {
            if (expectedType.equals(m.getInfoType())) {
                itv = m;
                break;
            }
        }
    }
    if (itv == null) {
        throw new CmpRequestorException("the response does not contain InfoTypeAndValue " + expectedType);
    }

    ASN1Encodable certListAsn1Object;
    if (xipkiAction == null) {
        certListAsn1Object = itv.getInfoValue();
    } else {
        certListAsn1Object = extractXipkiActionContent(itv.getInfoValue(), xipkiAction);
    }

    CertificateList certList = CertificateList.getInstance(certListAsn1Object);

    X509CRL crl;
    try {
        crl = new X509CRLObject(certList);
    } catch (CRLException e) {
        throw new CmpRequestorException("returned CRL is invalid: " + e.getMessage());
    }

    CRLResultType result = new CRLResultType();
    result.setCRL(crl);
    return result;
}

From source file:org.xipki.ca.common.cmp.CmpUtil.java

License:Open Source License

public static boolean isImplictConfirm(final PKIHeader header) {
    InfoTypeAndValue[] regInfos = header.getGeneralInfo();
    if (regInfos != null) {
        for (InfoTypeAndValue regInfo : regInfos) {
            if (CMPObjectIdentifiers.it_implicitConfirm.equals(regInfo.getInfoType())) {
                return true;
            }//from  w  w w.j av a2 s  .  co m
        }
    }
    return false;
}

From source file:org.xipki.ca.common.cmp.CmpUtil.java

License:Open Source License

public static CmpUtf8Pairs extract(final InfoTypeAndValue[] regInfos) {
    if (regInfos != null) {
        for (InfoTypeAndValue regInfo : regInfos) {
            if (CMPObjectIdentifiers.regInfo_utf8Pairs.equals(regInfo.getInfoType())) {
                String regInfoValue = ((ASN1String) regInfo.getInfoValue()).getString();
                return new CmpUtf8Pairs(regInfoValue);
            }/*from w w  w  . j a va  2s. c  o m*/
        }
    }

    return null;
}

From source file:org.xipki.ca.server.impl.X509CACmpResponder.java

License:Open Source License

private PKIBody cmpGeneralMsg(final PKIHeaderBuilder respHeader, final CmpControl cmpControl,
        final PKIHeader reqHeader, final PKIBody reqBody, final CmpRequestorInfo requestor, final String user,
        final ASN1OctetString tid, final AuditEvent auditEvent) throws InsuffientPermissionException {
    GenMsgContent genMsgBody = (GenMsgContent) reqBody.getContent();
    InfoTypeAndValue[] itvs = genMsgBody.toInfoTypeAndValueArray();

    InfoTypeAndValue itv = null;/*ww  w. j ava2  s. c  om*/
    if (itvs != null && itvs.length > 0) {
        for (InfoTypeAndValue _itv : itvs) {
            String itvType = _itv.getInfoType().getId();
            if (knownGenMsgIds.contains(itvType)) {
                itv = _itv;
                break;
            }
        }
    }

    if (itv == null) {
        String statusMessage = "PKIBody type " + PKIBody.TYPE_GEN_MSG + " is only supported with the sub-types "
                + knownGenMsgIds.toString();
        return createErrorMsgPKIBody(PKIStatus.rejection, PKIFailureInfo.badRequest, statusMessage);
    }

    InfoTypeAndValue itvResp = null;
    ASN1ObjectIdentifier infoType = itv.getInfoType();

    int failureInfo;
    try {
        X509CA ca = getCA();
        if (CMPObjectIdentifiers.it_currentCRL.equals(infoType)) {
            addAutitEventType(auditEvent, "CRL_DOWNLOAD");
            checkPermission(requestor, Permission.GET_CRL);
            CertificateList crl = ca.getCurrentCRL();

            if (itv.getInfoValue() == null) { // as defined in RFC 4210
                crl = ca.getCurrentCRL();
            } else {
                // xipki extension
                ASN1Integer crlNumber = ASN1Integer.getInstance(itv.getInfoValue());
                crl = ca.getCRL(crlNumber.getPositiveValue());
            }

            if (crl == null) {
                String statusMessage = "no CRL is available";
                return createErrorMsgPKIBody(PKIStatus.rejection, PKIFailureInfo.systemFailure, statusMessage);
            }

            itvResp = new InfoTypeAndValue(infoType, crl);
        } else if (ObjectIdentifiers.id_xipki_cmp.equals(infoType)) {
            ASN1Encodable asn1 = itv.getInfoValue();
            ASN1Integer asn1Code = null;
            ASN1Encodable reqValue = null;

            try {
                ASN1Sequence seq = ASN1Sequence.getInstance(asn1);
                asn1Code = ASN1Integer.getInstance(seq.getObjectAt(0));
                if (seq.size() > 1) {
                    reqValue = seq.getObjectAt(1);
                }
            } catch (IllegalArgumentException e) {
                String statusMessage = "invalid value of the InfoTypeAndValue for "
                        + ObjectIdentifiers.id_xipki_cmp.getId();
                return createErrorMsgPKIBody(PKIStatus.rejection, PKIFailureInfo.badRequest, statusMessage);
            }

            ASN1Encodable respValue;

            int action = asn1Code.getPositiveValue().intValue();
            switch (action) {
            case XipkiCmpConstants.ACTION_GEN_CRL:
                addAutitEventType(auditEvent, "CRL_GEN_ONDEMAND");
                checkPermission(requestor, Permission.GEN_CRL);
                X509CRL _crl = ca.generateCRLonDemand(auditEvent);
                if (_crl == null) {
                    String statusMessage = "CRL generation is not activated";
                    return createErrorMsgPKIBody(PKIStatus.rejection, PKIFailureInfo.systemFailure,
                            statusMessage);
                } else {
                    respValue = CertificateList.getInstance(_crl.getEncoded());
                }
                break;
            case XipkiCmpConstants.ACTION_GET_CRL_WITH_SN:
                addAutitEventType(auditEvent, "CRL_DOWNLOAD_WITH_SN");
                checkPermission(requestor, Permission.GET_CRL);

                ASN1Integer crlNumber = ASN1Integer.getInstance(reqValue);
                respValue = ca.getCRL(crlNumber.getPositiveValue());
                if (respValue == null) {
                    String statusMessage = "no CRL is available";
                    return createErrorMsgPKIBody(PKIStatus.rejection, PKIFailureInfo.systemFailure,
                            statusMessage);
                }
                break;
            case XipkiCmpConstants.ACTION_GET_CAINFO:
                addAutitEventType(auditEvent, "GET_SYSTEMINFO");
                Set<Integer> acceptVersions = new HashSet<>();
                if (reqValue != null) {
                    ASN1Sequence seq = DERSequence.getInstance(reqValue);
                    int size = seq.size();
                    for (int i = 0; i < size; i++) {
                        ASN1Integer a = ASN1Integer.getInstance(seq.getObjectAt(i));
                        acceptVersions.add(a.getPositiveValue().intValue());
                    }
                }

                if (CollectionUtil.isEmpty(acceptVersions)) {
                    acceptVersions.add(1);
                }

                String systemInfo = getSystemInfo(requestor, acceptVersions);
                respValue = new DERUTF8String(systemInfo);
                break;
            case XipkiCmpConstants.ACTION_REMOVE_EXPIRED_CERTS:
                checkPermission(requestor, Permission.REMOVE_CERT);

                String info = removeExpiredCerts(requestor, itv.getInfoValue());
                respValue = new DERUTF8String(info);
                break;
            default:
                String statusMessage = "unsupported XiPKI action code '" + action + "'";
                return createErrorMsgPKIBody(PKIStatus.rejection, PKIFailureInfo.badRequest, statusMessage);
            } // end switch(action)

            ASN1EncodableVector v = new ASN1EncodableVector();
            v.add(asn1Code);
            if (respValue != null) {
                v.add(respValue);
            }
            itvResp = new InfoTypeAndValue(infoType, new DERSequence(v));
        }

        GenRepContent genRepContent = new GenRepContent(itvResp);
        return new PKIBody(PKIBody.TYPE_GEN_REP, genRepContent);
    } catch (OperationException e) {
        failureInfo = PKIFailureInfo.systemFailure;
        String statusMessage = null;
        ErrorCode code = e.getErrorCode();
        switch (code) {
        case BAD_REQUEST:
            failureInfo = PKIFailureInfo.badRequest;
            statusMessage = e.getErrorMessage();
            break;
        case DATABASE_FAILURE:
        case SYSTEM_FAILURE:
            statusMessage = code.name();
            break;
        default:
            statusMessage = code.name() + ": " + e.getErrorMessage();
            break;
        } // end switch(code)

        return createErrorMsgPKIBody(PKIStatus.rejection, failureInfo, statusMessage);
    } catch (CRLException e) {
        String statusMessage = "CRLException: " + e.getMessage();
        return createErrorMsgPKIBody(PKIStatus.rejection, PKIFailureInfo.systemFailure, statusMessage);
    }
}

From source file:org.xipki.commons.remotep11.server.CmpResponder.java

License:Open Source License

PKIMessage processPkiMessage(final LocalP11CryptServicePool p11CryptServicePool, final String moduleName,
        final PKIMessage pkiMessage) {
    ParamUtil.requireNonNull("p11CryptServicePool", p11CryptServicePool);
    ParamUtil.requireNonNull("pkiMessage", pkiMessage);
    GeneralPKIMessage message = new GeneralPKIMessage(pkiMessage);

    PKIHeader reqHeader = message.getHeader();
    ASN1OctetString tid = reqHeader.getTransactionID();

    if (tid == null) {
        byte[] randomBytes = randomTransactionId();
        tid = new DEROctetString(randomBytes);
    }//from   w w  w  . j a va 2s.  co m
    String tidStr = Hex.toHexString(tid.getOctets());

    PKIHeaderBuilder respHeaderBuilder = new PKIHeaderBuilder(reqHeader.getPvno().getValue().intValue(), sender,
            reqHeader.getSender());
    respHeaderBuilder.setTransactionID(tid);

    PKIBody reqBody = message.getBody();
    final int type = reqBody.getType();

    PKIHeader respHeader = respHeaderBuilder.build();

    if (type != PKIBody.TYPE_GEN_MSG) {
        ErrorMsgContent emc = new ErrorMsgContent(new PKIStatusInfo(PKIStatus.rejection,
                new PKIFreeText("unsupported type " + type), new PKIFailureInfo(PKIFailureInfo.badRequest)));

        PKIBody respBody = new PKIBody(PKIBody.TYPE_ERROR, emc);
        return new PKIMessage(respHeader, respBody);
    }

    GenMsgContent genMsgBody = GenMsgContent.getInstance(reqBody.getContent());
    InfoTypeAndValue[] itvs = genMsgBody.toInfoTypeAndValueArray();

    InfoTypeAndValue itv = null;
    if (itvs != null && itvs.length > 0) {
        for (InfoTypeAndValue m : itvs) {
            ASN1ObjectIdentifier itvType = m.getInfoType();
            if (ObjectIdentifiers.id_xipki_cmp_cmpGenmsg.equals(itvType)) {
                itv = m;
                break;
            }
        }
    }

    if (itv == null) {
        final String statusMessage = String.format("PKIBody type %s is only supported with the sub-knownTypes",
                ObjectIdentifiers.id_xipki_cmp_cmpGenmsg.getId());
        return createRejectionPkiMessage(respHeader, PKIFailureInfo.badRequest, statusMessage);
    }

    try {
        return doProcessPkiMessage(p11CryptServicePool, moduleName, itv, respHeader);
    } catch (BadAsn1ObjectException ex) {
        LogUtil.error(LOG, ex, "could not process CMP message " + tidStr);
        return createRejectionPkiMessage(respHeader, PKIFailureInfo.badRequest, ex.getMessage());
    } catch (P11TokenException ex) {
        LogUtil.error(LOG, ex, "could not process CMP message " + tidStr);

        String p11ErrorType;
        if (ex instanceof P11UnknownEntityException) {
            p11ErrorType = P11ProxyConstants.ERROR_UNKNOWN_ENTITY;
        } else if (ex instanceof P11DuplicateEntityException) {
            p11ErrorType = P11ProxyConstants.ERROR_DUPLICATE_ENTITY;
        } else if (ex instanceof P11UnsupportedMechanismException) {
            p11ErrorType = P11ProxyConstants.ERROR_UNSUPPORTED_MECHANISM;
        } else {
            p11ErrorType = P11ProxyConstants.ERROR_P11_TOKENERROR;
        }

        String errorMessage = ex.getMessage();

        if (errorMessage == null) {
            errorMessage = "NULL";
        } else if (StringUtil.isBlank(errorMessage.trim())) {
            errorMessage = "NULL";
        }

        ConfPairs confPairs = new ConfPairs(p11ErrorType, errorMessage);
        return createRejectionPkiMessage(respHeader, PKIFailureInfo.badRequest, confPairs.getEncoded());
    } catch (Throwable th) {
        LogUtil.error(LOG, th, "could not process CMP message " + tidStr);
        return createRejectionPkiMessage(respHeader, PKIFailureInfo.systemFailure, "SYSTEM_FAILURE");
    }
}

From source file:org.xipki.commons.security.pkcs11.proxy.ProxyP11Module.java

License:Open Source License

private ASN1Encodable extractItvInfoValue(final int action, final GeneralPKIMessage response)
        throws P11TokenException {
    PKIBody respBody = response.getBody();
    int bodyType = respBody.getType();

    if (PKIBody.TYPE_ERROR == bodyType) {
        ErrorMsgContent content = (ErrorMsgContent) respBody.getContent();
        PKIStatusInfo statusInfo = content.getPKIStatusInfo();
        String failureInfo = null;
        if (statusInfo.getStatusString() != null) {
            int size = statusInfo.getStatusString().size();
            if (size > 0) {
                failureInfo = statusInfo.getStatusString().getStringAt(0).getString();
            }/*ww  w  . j a va2  s  .  c o m*/
        }

        if (failureInfo == null) {
            throw new P11TokenException(
                    "server answered with ERROR: " + CmpFailureUtil.formatPkiStatusInfo(statusInfo));
        }

        if (failureInfo.startsWith(P11ProxyConstants.ERROR_P11_TOKENERROR)) {
            ConfPairs pairs = new ConfPairs(failureInfo);
            String errorMesage = pairs.getValue(P11ProxyConstants.ERROR_P11_TOKENERROR);
            throw new P11TokenException(errorMesage);
        } else if (failureInfo.startsWith(P11ProxyConstants.ERROR_UNKNOWN_ENTITY)) {
            ConfPairs pairs = new ConfPairs(failureInfo);
            String errorMesage = pairs.getValue(P11ProxyConstants.ERROR_UNKNOWN_ENTITY);
            throw new P11UnknownEntityException(errorMesage);
        } else if (failureInfo.startsWith(P11ProxyConstants.ERROR_UNSUPPORTED_MECHANISM)) {
            ConfPairs pairs = new ConfPairs(failureInfo);
            String errorMesage = pairs.getValue(P11ProxyConstants.ERROR_UNSUPPORTED_MECHANISM);
            throw new P11UnsupportedMechanismException(errorMesage);
        } else if (failureInfo.startsWith(P11ProxyConstants.ERROR_DUPLICATE_ENTITY)) {
            ConfPairs pairs = new ConfPairs(failureInfo);
            String errorMesage = pairs.getValue(P11ProxyConstants.ERROR_UNSUPPORTED_MECHANISM);
            throw new P11DuplicateEntityException(errorMesage);
        } else {
            throw new P11TokenException(
                    "server answered with ERROR: " + CmpFailureUtil.formatPkiStatusInfo(statusInfo));
        }
    } else if (PKIBody.TYPE_GEN_REP != bodyType) {
        throw new P11TokenException("unknown PKI body type " + bodyType + " instead the expected ["
                + PKIBody.TYPE_GEN_REP + ", " + PKIBody.TYPE_ERROR + "]");
    }

    GenRepContent genRep = (GenRepContent) respBody.getContent();

    InfoTypeAndValue[] itvs = genRep.toInfoTypeAndValueArray();
    InfoTypeAndValue itv = null;
    if (itvs != null && itvs.length > 0) {
        for (InfoTypeAndValue m : itvs) {
            if (ObjectIdentifiers.id_xipki_cmp_cmpGenmsg.equals(m.getInfoType())) {
                itv = m;
                break;
            }
        }
    }
    if (itv == null) {
        throw new P11TokenException("the response does not contain InfoTypeAndValue '"
                + ObjectIdentifiers.id_xipki_cmp_cmpGenmsg.getId() + "'");
    }

    ASN1Encodable itvValue = itv.getInfoValue();
    if (itvValue == null) {
        throw new P11TokenException("value of InfoTypeAndValue '"
                + ObjectIdentifiers.id_xipki_cmp_cmpGenmsg.getId() + "' is incorrect");
    }

    try {
        ASN1Sequence seq = Asn1Util.getSequence(itvValue);
        Asn1Util.requireRange(seq, 2, 3);

        int receivedversion = Asn1Util.getInteger(seq.getObjectAt(0)).intValue();
        if (receivedversion != version) {
            throw new P11TokenException(
                    "version '" + receivedversion + "' is not the expected '" + version + "'");
        }

        int receivedAction = Asn1Util.getInteger(seq.getObjectAt(1)).intValue();
        if (receivedAction != action) {
            throw new P11TokenException("action '" + receivedAction + "' is not the expected '" + action + "'");
        }

        return (seq.size() > 2) ? seq.getObjectAt(2) : null;
    } catch (BadAsn1ObjectException ex) {
        throw new P11TokenException("bad ASN1 object: " + ex.getMessage(), ex);
    }
}

From source file:org.xipki.pki.ca.client.impl.CmpRequestor.java

License:Open Source License

private ASN1Encodable extractGeneralRepContent(final PkiResponse response, final String expectedType,
        final boolean requireProtectionCheck) throws CmpRequestorException, PkiErrorException {
    ParamUtil.requireNonNull("response", response);
    ParamUtil.requireNonNull("expectedType", expectedType);
    if (requireProtectionCheck) {
        checkProtection(response);/* w  w w  .jav  a  2 s  . c o  m*/
    }

    PKIBody respBody = response.getPkiMessage().getBody();
    int bodyType = respBody.getType();

    if (PKIBody.TYPE_ERROR == bodyType) {
        ErrorMsgContent content = ErrorMsgContent.getInstance(respBody.getContent());
        throw new CmpRequestorException(CmpFailureUtil.formatPkiStatusInfo(content.getPKIStatusInfo()));
    } else if (PKIBody.TYPE_GEN_REP != bodyType) {
        throw new CmpRequestorException(String.format("unknown PKI body type %s instead the expected [%s, %s]",
                bodyType, PKIBody.TYPE_GEN_REP, PKIBody.TYPE_ERROR));
    }

    GenRepContent genRep = GenRepContent.getInstance(respBody.getContent());

    InfoTypeAndValue[] itvs = genRep.toInfoTypeAndValueArray();
    InfoTypeAndValue itv = null;
    if (itvs != null && itvs.length > 0) {
        for (InfoTypeAndValue entry : itvs) {
            if (expectedType.equals(entry.getInfoType().getId())) {
                itv = entry;
                break;
            }
        }
    }
    if (itv == null) {
        throw new CmpRequestorException("the response does not contain InfoTypeAndValue " + expectedType);
    }

    return itv.getInfoValue();
}

From source file:org.xipki.pki.ca.client.impl.CmpRequestor.java

License:Open Source License

protected PKIHeader buildPkiHeader(final boolean addImplictConfirm, final ASN1OctetString tid,
        final CmpUtf8Pairs utf8Pairs, final InfoTypeAndValue... additionalGeneralInfos) {
    if (additionalGeneralInfos != null) {
        for (InfoTypeAndValue itv : additionalGeneralInfos) {
            ASN1ObjectIdentifier type = itv.getInfoType();
            if (CMPObjectIdentifiers.it_implicitConfirm.equals(type)) {
                throw new IllegalArgumentException(
                        "additionGeneralInfos contains not-permitted ITV implicitConfirm");
            }//from w ww  .ja  v a  2  s .c  om

            if (CMPObjectIdentifiers.regInfo_utf8Pairs.equals(type)) {
                throw new IllegalArgumentException("additionGeneralInfos contains not-permitted ITV utf8Pairs");
            }
        }
    }

    PKIHeaderBuilder hdrBuilder = new PKIHeaderBuilder(PKIHeader.CMP_2000, sender, recipient);
    hdrBuilder.setMessageTime(new ASN1GeneralizedTime(new Date()));

    ASN1OctetString tmpTid = (tid == null) ? new DEROctetString(randomTransactionId()) : tid;
    hdrBuilder.setTransactionID(tmpTid);

    List<InfoTypeAndValue> itvs = new ArrayList<>(2);
    if (addImplictConfirm) {
        itvs.add(CmpUtil.getImplictConfirmGeneralInfo());
    }

    if (utf8Pairs != null) {
        itvs.add(CmpUtil.buildInfoTypeAndValue(utf8Pairs));
    }

    if (additionalGeneralInfos != null) {
        for (InfoTypeAndValue itv : additionalGeneralInfos) {
            if (itv != null) {
                itvs.add(itv);
            }
        }
    }

    if (CollectionUtil.isNonEmpty(itvs)) {
        hdrBuilder.setGeneralInfo(itvs.toArray(new InfoTypeAndValue[0]));
    }

    return hdrBuilder.build();
}