Сервис проблем Добавить TimeStamp к CADES-T Sign - PullRequest
0 голосов
/ 14 марта 2019

Когда я использую URL-адрес службы TimeStamp и помещаю его в качестве атрибута в сигнатуру CAdES-T. Я использовал следующие услуги: http://psis.catcert.net/psis/catcert/tsp (ответ идет с токеном) http://timestamp.comodoca.com (ответ приходит без токена) У меня вопрос, должен ли я обработать подписанный файл другим способом, чтобы использовать метку времени?

public byte[] addTimestamp(final byte[] pkcs7, final String hashAlgorithm, final Calendar time) throws NoSuchAlgorithmException, AOException, IOException, TSPException, NoSuchProviderException {**

    final String digestAlgorithm = AOSignConstants.getDigestAlgorithmName(hashAlgorithm);

    CMSSignedData signedData;
    try {
        signedData = new CMSSignedData(pkcs7);
    }
    catch (final Exception e) {
        throw new IllegalArgumentException("The input data is not a CMS SignedData: " + e);
    }

    final SignerInformationStore origSignerInfoStore =  signedData.getSignerInfos();

    final List<SignerInformation> vNewSigners = new ArrayList<>();

    final Collection<?> ovSigners = origSignerInfoStore.getSigners();
    for (final Object name : ovSigners) {

        final SignerInformation si = (SignerInformation) name;  
        final byte[] tsToken = getTimeStampToken(
            MessageDigest.getInstance(digestAlgorithm).digest(si.getSignature()),
            digestAlgorithm,
            time
        );

        final ASN1Primitive derObj;
        try (
            final ASN1InputStream is = new ASN1InputStream(new ByteArrayInputStream(tsToken));
        ) {
            derObj = is.readObject();
        }
        final DERSet derSet = new DERSet(derObj);

        final Attribute unsignAtt = new Attribute(new ASN1ObjectIdentifier(SIGNATURE_TIMESTAMP_TOKEN_OID), derSet);

        final Hashtable<ASN1ObjectIdentifier, Attribute> ht = new Hashtable<>();
        ht.put(new ASN1ObjectIdentifier(SIGNATURE_TIMESTAMP_TOKEN_OID), unsignAtt);

        final AttributeTable unsignedAtts = new AttributeTable(ht);

        vNewSigners.add(SignerInformation.replaceUnsignedAttributes(si, unsignedAtts));
    }

    return CMSSignedData.replaceSigners(signedData, new SignerInformationStore(vNewSigners)).getEncoded();
}
public byte[] getTimeStampToken(final byte[] imprint, final String hashAlgorithm, final Calendar time) throws AOException, IOException {**

    final TimeStampRequest request = this.tsqGenerator.generate(
        new ASN1ObjectIdentifier(hashAlgorithm != null ? AOAlgorithmID.getOID(hashAlgorithm) : X509ObjectIdentifiers.id_SHA1.getId()),
        imprint,
        BigInteger.valueOf(time != null ? time.getTimeInMillis() : System.currentTimeMillis())
    );

    final byte[] requestBytes = request.getEncoded();

    final byte[] rawResponse = getTSAResponse(requestBytes);

    TimeStampResponse response = null;
    try {
        response = new TimeStampResponse(rawResponse);
    }
    catch (final Exception e) {
        LOGGER.severe("TSA response: " + response.getStatusString());
        throw new AOException("Error getting the response from the TSA: " + e, e);
    }

    //Validate the attributes of the response (RFC 3161 PKIStatus)
    try {
    response.validate(request);
    }
    catch (final Exception e) {
    throw new AOException("Error validating the response of the TSA: " + e, e);
    }

    final PKIFailureInfo failure = response.getFailInfo();
    final int value = failure == null ? 0 : failure.intValue();
    if (value != 0) {
        throw new AOException("Invalid response from the TSA ('" + this.tsaURL + "') with the code " + value);
    }

    //We extract the time stamp token (removing the status information from the communications)
    final TimeStampToken  tsToken = response.getTimeStampToken();
    if (tsToken == null) {
        throw new AOException("The response of the TSA ('" + this.tsaURL + "') is not a valid time stamp: " + response.getStatusString());
    }

    return tsToken.getEncoded();
}
private byte[] getTSAResponse(final byte[] request) throws IOException {

        if (this.tsaURL.getScheme().equals("socket")) {
            return getTSAResponseSocket(request);
        }
        if (this.tsaURL.getScheme().equals("http")) {
            return getTSAResponseHttp(request);
        }
        if (this.tsaURL.getScheme().equals("https")) {
            return getTSAResponseHttps(request);
        }
        throw new UnsupportedOperationException("Connection protocol with TSA not supported: " + this.tsaURL.getScheme());
}
...