Example usage for org.bouncycastle.cert.ocsp OCSPResp getResponseObject

List of usage examples for org.bouncycastle.cert.ocsp OCSPResp getResponseObject

Introduction

In this page you can find the example usage for org.bouncycastle.cert.ocsp OCSPResp getResponseObject.

Prototype

public Object getResponseObject() throws OCSPException 

Source Link

Usage

From source file:be.fedict.trust.ocsp.OcspTrustLinker.java

License:Open Source License

@Override
public TrustLinkerResult hasTrustLink(X509Certificate childCertificate, X509Certificate certificate,
        Date validationDate, RevocationData revocationData, AlgorithmPolicy algorithmPolicy)
        throws TrustLinkerResultException, Exception {
    URI ocspUri = getOcspUri(childCertificate);
    if (null == ocspUri) {
        return TrustLinkerResult.UNDECIDED;
    }/*from  w w  w  .  j a v a  2s .  c o m*/
    LOG.debug("OCSP URI: " + ocspUri);

    OCSPResp ocspResp = this.ocspRepository.findOcspResponse(ocspUri, childCertificate, certificate,
            validationDate);
    if (null == ocspResp) {
        LOG.debug("OCSP response not found");
        return TrustLinkerResult.UNDECIDED;
    }

    int ocspRespStatus = ocspResp.getStatus();
    if (OCSPResponseStatus.SUCCESSFUL != ocspRespStatus) {
        LOG.debug("OCSP response status: " + ocspRespStatus);
        return TrustLinkerResult.UNDECIDED;
    }

    Object responseObject = ocspResp.getResponseObject();
    BasicOCSPResp basicOCSPResp = (BasicOCSPResp) responseObject;

    X509CertificateHolder[] responseCertificates = basicOCSPResp.getCerts();
    for (X509CertificateHolder responseCertificate : responseCertificates) {
        LOG.debug("OCSP response cert: " + responseCertificate.getSubject());
        LOG.debug("OCSP response cert issuer: " + responseCertificate.getIssuer());
    }

    algorithmPolicy.checkSignatureAlgorithm(basicOCSPResp.getSignatureAlgOID().getId(), validationDate);

    if (0 == responseCertificates.length) {
        /*
         * This means that the OCSP response has been signed by the issuing
         * CA itself.
         */
        ContentVerifierProvider contentVerifierProvider = new JcaContentVerifierProviderBuilder()
                .setProvider(BouncyCastleProvider.PROVIDER_NAME).build(certificate.getPublicKey());
        boolean verificationResult = basicOCSPResp.isSignatureValid(contentVerifierProvider);
        if (false == verificationResult) {
            LOG.debug("OCSP response signature invalid");
            return TrustLinkerResult.UNDECIDED;
        }
    } else {
        /*
         * We're dealing with a dedicated authorized OCSP Responder
         * certificate, or of course with a CA that issues the OCSP
         * Responses itself.
         */

        X509CertificateHolder ocspResponderCertificate = responseCertificates[0];
        ContentVerifierProvider contentVerifierProvider = new JcaContentVerifierProviderBuilder()
                .setProvider(BouncyCastleProvider.PROVIDER_NAME).build(ocspResponderCertificate);

        boolean verificationResult = basicOCSPResp.isSignatureValid(contentVerifierProvider);
        if (false == verificationResult) {
            LOG.debug("OCSP Responser response signature invalid");
            return TrustLinkerResult.UNDECIDED;
        }
        if (false == Arrays.equals(certificate.getEncoded(), ocspResponderCertificate.getEncoded())) {
            // check certificate signature algorithm
            algorithmPolicy.checkSignatureAlgorithm(
                    ocspResponderCertificate.getSignatureAlgorithm().getAlgorithm().getId(), validationDate);

            X509Certificate issuingCaCertificate;
            if (responseCertificates.length < 2) {
                // so the OCSP certificate chain only contains a single
                // entry
                LOG.debug("OCSP responder complete certificate chain missing");
                /*
                 * Here we assume that the OCSP Responder is directly signed
                 * by the CA.
                 */
                issuingCaCertificate = certificate;
            } else {
                CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
                issuingCaCertificate = (X509Certificate) certificateFactory
                        .generateCertificate(new ByteArrayInputStream(responseCertificates[1].getEncoded()));
                /*
                 * Is next check really required?
                 */
                if (false == certificate.equals(issuingCaCertificate)) {
                    LOG.debug("OCSP responder certificate not issued by CA");
                    return TrustLinkerResult.UNDECIDED;
                }
            }
            // check certificate signature
            algorithmPolicy.checkSignatureAlgorithm(issuingCaCertificate.getSigAlgOID(), validationDate);

            PublicKeyTrustLinker publicKeyTrustLinker = new PublicKeyTrustLinker();
            CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
            X509Certificate x509OcspResponderCertificate = (X509Certificate) certificateFactory
                    .generateCertificate(new ByteArrayInputStream(ocspResponderCertificate.getEncoded()));
            LOG.debug("OCSP Responder public key fingerprint: "
                    + DigestUtils.sha1Hex(x509OcspResponderCertificate.getPublicKey().getEncoded()));
            publicKeyTrustLinker.hasTrustLink(x509OcspResponderCertificate, issuingCaCertificate,
                    validationDate, revocationData, algorithmPolicy);
            if (null == x509OcspResponderCertificate
                    .getExtensionValue(OCSPObjectIdentifiers.id_pkix_ocsp_nocheck.getId())) {
                LOG.debug("OCSP Responder certificate should have id-pkix-ocsp-nocheck");
                /*
                 * TODO: perform CRL validation on the OCSP Responder
                 * certificate. On the other hand, do we really want to
                 * check the checker?
                 */
                return TrustLinkerResult.UNDECIDED;
            }
            List<String> extendedKeyUsage = x509OcspResponderCertificate.getExtendedKeyUsage();
            if (null == extendedKeyUsage) {
                LOG.debug("OCSP Responder certificate has no extended key usage extension");
                return TrustLinkerResult.UNDECIDED;
            }
            if (false == extendedKeyUsage.contains(KeyPurposeId.id_kp_OCSPSigning.getId())) {
                LOG.debug("OCSP Responder certificate should have a OCSPSigning extended key usage");
                return TrustLinkerResult.UNDECIDED;
            }
        } else {
            LOG.debug("OCSP Responder certificate equals the CA certificate");
            // and the CA certificate is already trusted at this point
        }
    }

    DigestCalculatorProvider digCalcProv = new JcaDigestCalculatorProviderBuilder()
            .setProvider(BouncyCastleProvider.PROVIDER_NAME).build();
    CertificateID certificateId = new CertificateID(digCalcProv.get(CertificateID.HASH_SHA1),
            new JcaX509CertificateHolder(certificate), childCertificate.getSerialNumber());

    SingleResp[] singleResps = basicOCSPResp.getResponses();
    for (SingleResp singleResp : singleResps) {
        CertificateID responseCertificateId = singleResp.getCertID();
        if (false == certificateId.equals(responseCertificateId)) {
            continue;
        }
        DateTime thisUpdate = new DateTime(singleResp.getThisUpdate());
        DateTime nextUpdate;
        if (null != singleResp.getNextUpdate()) {
            nextUpdate = new DateTime(singleResp.getNextUpdate());
        } else {
            LOG.debug("no OCSP nextUpdate");
            nextUpdate = thisUpdate;
        }
        LOG.debug("OCSP thisUpdate: " + thisUpdate);
        LOG.debug("(OCSP) nextUpdate: " + nextUpdate);
        DateTime beginValidity = thisUpdate.minus(this.freshnessInterval);
        DateTime endValidity = nextUpdate.plus(this.freshnessInterval);
        DateTime validationDateTime = new DateTime(validationDate);
        if (validationDateTime.isBefore(beginValidity)) {
            LOG.warn("OCSP response not yet valid");
            continue;
        }
        if (validationDateTime.isAfter(endValidity)) {
            LOG.warn("OCSP response expired");
            continue;
        }
        if (null == singleResp.getCertStatus()) {
            LOG.debug("OCSP OK for: " + childCertificate.getSubjectX500Principal());
            addRevocationData(revocationData, ocspResp, ocspUri);
            return TrustLinkerResult.TRUSTED;
        } else {
            LOG.debug("OCSP certificate status: " + singleResp.getCertStatus().getClass().getName());
            if (singleResp.getCertStatus() instanceof RevokedStatus) {
                LOG.debug("OCSP status revoked");
            }
            addRevocationData(revocationData, ocspResp, ocspUri);
            throw new TrustLinkerResultException(TrustLinkerResultReason.INVALID_REVOCATION_STATUS,
                    "certificate revoked by OCSP");
        }
    }

    LOG.debug("no matching OCSP response entry");
    return TrustLinkerResult.UNDECIDED;
}

From source file:be.fedict.trust.ocsp.OfflineOcspRepository.java

License:Open Source License

@Override
public OCSPResp findOcspResponse(URI ocspUri, X509Certificate certificate, X509Certificate issuerCertificate,
        Date validationDate) {/*w  ww  .  jav a  2  s. c  o  m*/

    LOG.debug("find OCSP response");

    DigestCalculatorProvider digCalcProv;
    try {
        digCalcProv = new JcaDigestCalculatorProviderBuilder().setProvider(BouncyCastleProvider.PROVIDER_NAME)
                .build();
    } catch (OperatorCreationException e) {
        throw new RuntimeException(e);
    }

    CertificateID certId;
    try {
        certId = new CertificateID(digCalcProv.get(CertificateID.HASH_SHA1),
                new JcaX509CertificateHolder(issuerCertificate), certificate.getSerialNumber());
    } catch (Exception e) {
        throw new RuntimeException(e);
    }

    try {
        for (OCSPResp ocspResp : this.ocspResponses) {
            BasicOCSPResp basicOCSPResp = (BasicOCSPResp) ocspResp.getResponseObject();
            for (SingleResp singleResp : basicOCSPResp.getResponses()) {
                if (singleResp.getCertID().equals(certId)) {
                    LOG.debug("OCSP response found");
                    return ocspResp;
                }
            }
        }
    } catch (OCSPException e) {
        LOG.error("OCSPException: " + e.getMessage(), e);
        return null;
    }

    LOG.debug("OCSP response not found");
    return null;
}

From source file:com.itextpdf.signatures.LtvVerifier.java

License:Open Source License

/**
 * Gets OCSP responses from the Document Security Store.
 * @return   a list of BasicOCSPResp objects
 * @throws IOException/*from www .j a  va 2s. c  o  m*/
 * @throws GeneralSecurityException
 */
public List<BasicOCSPResp> getOCSPResponsesFromDSS() throws IOException, GeneralSecurityException {
    List<BasicOCSPResp> ocsps = new ArrayList<>();
    if (dss == null)
        return ocsps;
    PdfArray ocsparray = dss.getAsArray(PdfName.OCSPs);
    if (ocsparray == null)
        return ocsps;
    for (int i = 0; i < ocsparray.size(); i++) {
        PdfStream stream = ocsparray.getAsStream(i);
        OCSPResp ocspResponse = new OCSPResp(stream.getBytes());
        if (ocspResponse.getStatus() == 0)
            try {
                ocsps.add((BasicOCSPResp) ocspResponse.getResponseObject());
            } catch (OCSPException e) {
                throw new GeneralSecurityException(e.toString());
            }
    }
    return ocsps;
}

From source file:com.itextpdf.signatures.OcspClientBouncyCastle.java

License:Open Source License

/**
 * Gets OCSP response. If {@see OCSPVerifier} was setted, the response will be checked.
 *//*  w  w w.  ja v a2s . c o m*/
public BasicOCSPResp getBasicOCSPResp(X509Certificate checkCert, X509Certificate rootCert, String url) {
    try {
        OCSPResp ocspResponse = getOcspResponse(checkCert, rootCert, url);
        if (ocspResponse == null) {
            return null;
        }
        if (ocspResponse.getStatus() != OCSPRespStatus.SUCCESSFUL) {
            return null;
        }
        BasicOCSPResp basicResponse = (BasicOCSPResp) ocspResponse.getResponseObject();
        if (verifier != null) {
            verifier.isValidResponse(basicResponse, rootCert);
        }
        return basicResponse;
    } catch (Exception ex) {
        LOGGER.error(ex.getMessage());
    }
    return null;
}

From source file:com.itextpdf.text.pdf.security.LtvVerifier.java

License:Open Source License

/**
 * Gets OCSP responses from the Document Security Store.
 * @return   a list of BasicOCSPResp objects
 * @throws IOException/*from  ww  w.j  a v a 2  s . c  om*/
 * @throws GeneralSecurityException
 */
public List<BasicOCSPResp> getOCSPResponsesFromDSS() throws IOException, GeneralSecurityException {
    List<BasicOCSPResp> ocsps = new ArrayList<BasicOCSPResp>();
    if (dss == null)
        return ocsps;
    PdfArray ocsparray = dss.getAsArray(PdfName.OCSPS);
    if (ocsparray == null)
        return ocsps;
    for (int i = 0; i < ocsparray.size(); i++) {
        PRStream stream = (PRStream) ocsparray.getAsStream(i);
        OCSPResp ocspResponse = new OCSPResp(PdfReader.getStreamBytes(stream));
        if (ocspResponse.getStatus() == 0)
            try {
                ocsps.add((BasicOCSPResp) ocspResponse.getResponseObject());
            } catch (OCSPException e) {
                throw new GeneralSecurityException(e);
            }
    }
    return ocsps;
}

From source file:com.itextpdf.text.pdf.security.OcspClientBouncyCastle.java

License:Open Source License

public BasicOCSPResp getBasicOCSPResp(X509Certificate checkCert, X509Certificate rootCert, String url) {
    try {// w  w  w  .  j  a v a2  s  .c  om
        OCSPResp ocspResponse = getOcspResponse(checkCert, rootCert, url);
        if (ocspResponse == null)
            return null;
        if (ocspResponse.getStatus() != 0)
            return null;
        return (BasicOCSPResp) ocspResponse.getResponseObject();
    } catch (Exception ex) {
        if (LOGGER.isLogging(Level.ERROR))
            LOGGER.error(ex.getMessage());
    }
    return null;
}

From source file:com.swisscom.ais.itext.PDF.java

License:Open Source License

/** 
 * Add external revocation information to DSS Dictionary, to enable Long Term Validation (LTV) in Adobe Reader
 * /* w  ww .  ja v  a  2 s.  com*/
 * @param ocspArr List of OCSP Responses as base64 encoded String
 * @param crlArr  List of CRLs as base64 encoded String
 * @throws Exception 
 */
public void addValidationInformation(ArrayList<String> ocspArr, ArrayList<String> crlArr) throws Exception {
    if (ocspArr == null && crlArr == null)
        return;

    PdfReader reader = new PdfReader(outputFilePath);

    // Check if source pdf is not protected by a certification
    if (reader.getCertificationLevel() == PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED)
        throw new Exception(
                "Could not apply revocation information (LTV) to the DSS Dictionary. Document contains a certification that does not allow any changes.");

    Collection<byte[]> ocspColl = new ArrayList<byte[]>();
    Collection<byte[]> crlColl = new ArrayList<byte[]>();

    // Decode each OCSP Response (String of base64 encoded form) and add it to the Collection (byte[])
    if (ocspArr != null) {
        for (String ocspBase64 : ocspArr) {
            OCSPResp ocspResp = new OCSPResp(new ByteArrayInputStream(Base64.decode(ocspBase64)));
            BasicOCSPResp basicResp = (BasicOCSPResp) ocspResp.getResponseObject();

            if (Soap._debugMode) {
                System.out.println("\nEmbedding OCSP Response...");
                System.out.println("Status                : " + ((ocspResp.getStatus() == 0) ? "GOOD" : "BAD"));
                System.out.println("Produced at           : " + basicResp.getProducedAt());
                System.out.println("This Update           : " + basicResp.getResponses()[0].getThisUpdate());
                System.out.println("Next Update           : " + basicResp.getResponses()[0].getNextUpdate());
                System.out.println("X509 Cert Issuer      : " + basicResp.getCerts()[0].getIssuer());
                System.out.println("X509 Cert Subject     : " + basicResp.getCerts()[0].getSubject());
                System.out.println(
                        "Responder ID X500Name : " + basicResp.getResponderId().toASN1Object().getName());
                System.out.println("Certificate ID        : "
                        + basicResp.getResponses()[0].getCertID().getSerialNumber().toString() + " ("
                        + basicResp.getResponses()[0].getCertID().getSerialNumber().toString(16).toUpperCase()
                        + ")");
            }

            ocspColl.add(basicResp.getEncoded()); // Add Basic OCSP Response to Collection (ASN.1 encoded representation of this object)
        }
    }

    // Decode each CRL (String of base64 encoded form) and add it to the Collection (byte[])
    if (crlArr != null) {
        for (String crlBase64 : crlArr) {
            X509CRL x509crl = (X509CRL) CertificateFactory.getInstance("X.509")
                    .generateCRL(new ByteArrayInputStream(Base64.decode(crlBase64)));

            if (Soap._debugMode) {
                System.out.println("\nEmbedding CRL...");
                System.out.println("IssuerDN                    : " + x509crl.getIssuerDN());
                System.out.println("This Update                 : " + x509crl.getThisUpdate());
                System.out.println("Next Update                 : " + x509crl.getNextUpdate());
                System.out.println(
                        "No. of Revoked Certificates : " + ((x509crl.getRevokedCertificates() == null) ? "0"
                                : x509crl.getRevokedCertificates().size()));
            }

            crlColl.add(x509crl.getEncoded()); // Add CRL to Collection (ASN.1 DER-encoded form of this CRL)
        }
    }

    byteArrayOutputStream = new ByteArrayOutputStream();
    PdfStamper stamper = new PdfStamper(reader, byteArrayOutputStream, '\0', true);
    LtvVerification validation = stamper.getLtvVerification();

    // Add the CRL/OCSP validation information to the DSS Dictionary
    boolean addVerification = false;
    for (String sigName : stamper.getAcroFields().getSignatureNames()) {
        addVerification = validation.addVerification(sigName, // Signature Name
                ocspColl, // OCSP
                crlColl, // CRL
                null // certs
        );
    }

    validation.merge(); // Merges the validation with any validation already in the document or creates a new one.

    stamper.close();
    reader.close();

    // Save to (same) file
    OutputStream outputStream = new FileOutputStream(outputFilePath);
    byteArrayOutputStream.writeTo(outputStream);

    if (Soap._debugMode) {
        if (addVerification)
            System.out.println("\nOK merging LTV validation information to " + outputFilePath);
        else
            System.out.println("\nFAILED merging LTV validation information to " + outputFilePath);
    }

    byteArrayOutputStream.close();
    outputStream.close();
}

From source file:com.tremolosecurity.proxy.auth.ssl.OCSP.java

License:Apache License

@Override
public boolean isValid(X509Certificate cert, X509Certificate issuer) {
    try {/*ww  w. j a  v  a  2  s. c  o m*/
        OCSPReq ocspRequest = generateOcspRequest(issuer, cert.getSerialNumber());
        URL url = new URL(this.url);
        HttpURLConnection url_con = (HttpURLConnection) url.openConnection();

        url_con.setDoOutput(true);
        url_con.connect();
        OutputStream os = url_con.getOutputStream();
        os.write(ocspRequest.getEncoded());

        InputStream is = url_con.getInputStream();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        byte[] buffer = new byte[1024];
        int len = 0;

        do {
            len = is.read(buffer);
            if (len > 0) {
                baos.write(buffer, 0, len);
            }
        } while (len > 0);

        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());

        OCSPResp ocspResponse = new OCSPResp(bais);

        BasicOCSPResp resp = (BasicOCSPResp) ocspResponse.getResponseObject();

        //System.err.println(resp.getResponses()[0].getCertStatus());

        return resp.getResponses()[0].getCertStatus() == null || (!(resp.getResponses()[0]
                .getCertStatus() instanceof org.bouncycastle.cert.ocsp.RevokedStatus));

    } catch (Exception e) {
        logger.error("Error validating certificate", e);
        return false;
    }
}

From source file:ec.rubrica.ocsp.ValidadorOCSP.java

License:Open Source License

public static void check(X509Certificate issuerCert, X509Certificate x509Cert)
        throws OcspValidationException, OcspTimeoutException {
    try {//  w  ww.  j a  v  a2 s  .c  om
        BigInteger serialNumber = x509Cert.getSerialNumber();
        X509CertificateHolder holder;

        try {
            holder = new X509CertificateHolder(issuerCert.getEncoded());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        CertificateID id = new CertificateID(new JcaDigestCalculatorProviderBuilder()
                .setProvider(BouncyCastleProvider.PROVIDER_NAME).build().get(CertificateID.HASH_SHA1), holder,
                serialNumber);

        OCSPReqBuilder ocspGen = new OCSPReqBuilder();
        ocspGen.addRequest(id);
        OCSPReq ocspReq = ocspGen.build();

        // Ir al OCSP
        String ocspUrl = CertificateUtil.getOCSPURL(x509Cert);

        if (ocspUrl == null) {
            logger.info("URL de OCSP is null");
            return;
        }

        URL url;

        try {
            url = new URL(ocspUrl);
        } catch (MalformedURLException e) {
            throw new RuntimeException(e);
        }

        HttpURLConnection con;
        OCSPResp ocspResponse;

        try {
            con = (HttpURLConnection) url.openConnection();

            con.setRequestProperty("Content-Type", "application/ocsp-request");
            con.setRequestProperty("Accept", "application/ocsp-response");
            con.setDoOutput(true);

            OutputStream out = con.getOutputStream();
            DataOutputStream dataOut = new DataOutputStream(new BufferedOutputStream(out));
            dataOut.write(ocspReq.getEncoded());

            dataOut.flush();
            dataOut.close();

            /*
             * Se parsea la respuesta y se obtiene el estado del certificado
             * retornado por el OCSP
             */
            InputStream in = (InputStream) con.getContent();
            byte[] resp = read(in); // Read the reponse
            ocspResponse = new OCSPResp(resp);
        } catch (IOException e) {
            throw new OcspTimeoutException(url);
        }

        int status = ocspResponse.getStatus();
        System.out.println("status=" + status);

        BasicOCSPResp basicResponse = (BasicOCSPResp) ocspResponse.getResponseObject();

        if (basicResponse != null) {
            SingleResp[] responses = basicResponse.getResponses();
            SingleResp response = responses[0];
            CertificateStatus certStatus = response.getCertStatus();

            if (certStatus instanceof RevokedStatus) {
                System.out.println("REVOKED");
                RevokedStatus revokedStatus = (RevokedStatus) certStatus;
                System.out.println("Reason: " + revokedStatus.getRevocationReason());
                System.out.println("Date: " + revokedStatus.getRevocationTime());

                throw new OcspValidationException(revokedStatus.getRevocationReason(),
                        revokedStatus.getRevocationTime());
            }
        }
    } catch (OCSPException e) {
        throw new RuntimeException(e);
    } catch (CertificateEncodingException e) {
        throw new RuntimeException(e);
    } catch (OperatorCreationException e) {
        throw new RuntimeException(e);
    }
}

From source file:ee.ria.xroad.common.asic.AsicContainerVerifier.java

License:Open Source License

/**
 * Attempts to verify the ASiC container's signature and timestamp.
 * @throws Exception if verification was unsuccessful
 *//* w w w. j  ava 2  s .  c o m*/
public void verify() throws Exception {
    String message = asic.getMessage();
    SignatureData signatureData = asic.getSignature();
    signature = new Signature(signatureData.getSignatureXml());
    signerName = getSigner(message);

    SignatureVerifier signatureVerifier = new SignatureVerifier(signature, signatureData.getHashChainResult(),
            signatureData.getHashChain());
    verifyRequiredReferencesExist();

    Date atDate = verifyTimestamp();

    configureResourceResolvers(signatureVerifier);

    // Do not verify the schema, since the signature in the ASiC container
    // may contain the XadesTimeStamp element, which is not standard.
    signatureVerifier.setVerifySchema(false);

    // Add required part "message" to the hash chain verifier.
    signatureVerifier.addPart(new MessagePart(MESSAGE, null, null, null));

    signatureVerifier.verify(signerName, atDate);
    signerCert = signatureVerifier.getSigningCertificate();

    OCSPResp ocsp = signatureVerifier.getSigningOcspResponse(signerName.getXRoadInstance());
    ocspDate = ((BasicOCSPResp) ocsp.getResponseObject()).getProducedAt();
    ocspCert = OcspVerifier.getOcspCert((BasicOCSPResp) ocsp.getResponseObject());
}