Example usage for org.bouncycastle.openpgp PGPOnePassSignatureList get

List of usage examples for org.bouncycastle.openpgp PGPOnePassSignatureList get

Introduction

In this page you can find the example usage for org.bouncycastle.openpgp PGPOnePassSignatureList get.

Prototype

public PGPOnePassSignature get(int index) 

Source Link

Usage

From source file:alpha.offsync.security.OpenPGPSecurityUtility.java

License:Apache License

@Override
public void verify(OutputStream outputStream, final InputStream inputStream) {

    try {//from  w  w  w  . j a v  a 2  s . c o  m
        final File keyFile = this.publicKeyRing;

        final InputStream in = PGPUtil.getDecoderStream(inputStream);

        PGPObjectFactory pgpFact = new PGPObjectFactory(in);

        final PGPCompressedData c1 = (PGPCompressedData) pgpFact.nextObject();

        pgpFact = new PGPObjectFactory(c1.getDataStream());

        final PGPOnePassSignatureList p1 = (PGPOnePassSignatureList) pgpFact.nextObject();

        final PGPOnePassSignature ops = p1.get(0);

        final PGPLiteralData p2 = (PGPLiteralData) pgpFact.nextObject();

        final InputStream dIn = p2.getInputStream();
        int ch;
        final PGPPublicKeyRingCollection pgpRing = new PGPPublicKeyRingCollection(
                PGPUtil.getDecoderStream(new FileInputStream(keyFile)));

        final PGPPublicKey key = pgpRing.getPublicKey(ops.getKeyID());

        ops.init(new BcPGPContentVerifierBuilderProvider(), key);

        while ((ch = dIn.read()) >= 0) {
            ops.update((byte) ch);
            outputStream.write(ch);
        }

        outputStream.close();

        final PGPSignatureList p3 = (PGPSignatureList) pgpFact.nextObject();

        if (!ops.verify(p3.get(0))) {
            outputStream = null;
        }
    } catch (final FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (final SignatureException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (final IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (final PGPException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

From source file:com.arcusx.simplepgp.PgpDataDecryptor.java

public void decrypt(InputStream encryptedIn, InputStream privateKeyIn, InputStream publicKeyIn,
        OutputStream plainOut, boolean signatureRequired) throws PGPException, IOException {
    encryptedIn = PGPUtil.getDecoderStream(encryptedIn);

    try {//from  www. j  av a 2  s  .  co  m
        JcaPGPObjectFactory pgpObjectFactory = new JcaPGPObjectFactory(encryptedIn);

        Object o = pgpObjectFactory.nextObject();

        //
        // the first object might be a PGP marker packet.
        //
        PGPEncryptedDataList enc;
        if (o instanceof PGPEncryptedDataList) {
            enc = (PGPEncryptedDataList) o;
        } else {
            enc = (PGPEncryptedDataList) pgpObjectFactory.nextObject();
        }

        //
        // find the secret key
        //
        Iterator it = enc.getEncryptedDataObjects();
        PGPPrivateKey privateKey = null;
        PGPPublicKeyEncryptedData publicKeyEncryptedData = null;
        PGPSecretKeyRingCollection privateKeyRingCollection = new PGPSecretKeyRingCollection(
                PGPUtil.getDecoderStream(privateKeyIn), new JcaKeyFingerprintCalculator());

        while (privateKey == null && it.hasNext()) {
            publicKeyEncryptedData = (PGPPublicKeyEncryptedData) it.next();
            privateKey = findSecretKey(privateKeyRingCollection, publicKeyEncryptedData.getKeyID(),
                    "".toCharArray());
        }

        if (privateKey == null) {
            throw new IllegalArgumentException("Secret key for message not found.");
        }

        PublicKeyDataDecryptorFactory decryptorFactory = new JcePublicKeyDataDecryptorFactoryBuilder()
                .setProvider("BC").build(privateKey);
        InputStream clearTextIn = publicKeyEncryptedData.getDataStream(decryptorFactory);

        PGPOnePassSignature onePassSignature = null;
        JcaPGPObjectFactory pgpFact = new JcaPGPObjectFactory(clearTextIn);

        Object message = pgpFact.nextObject();
        if (message instanceof PGPCompressedData) {
            PGPCompressedData cData = (PGPCompressedData) message;
            pgpFact = new JcaPGPObjectFactory(cData.getDataStream());

            message = pgpFact.nextObject();
        }

        if (message instanceof PGPOnePassSignatureList) {
            PGPOnePassSignatureList onePassSignatureList = (PGPOnePassSignatureList) message;
            onePassSignature = onePassSignatureList.get(0);
            message = pgpFact.nextObject();
        }

        if (onePassSignature == null && signatureRequired) {
            throw new SecurityException("No signature object found.");
        }

        if (message instanceof PGPLiteralData) {
            PGPLiteralData literalData = (PGPLiteralData) message;
            InputStream literalDataIn = literalData.getInputStream();

            PGPPublicKey publicKey = PgpKeyUtils.readPublicKey(publicKeyIn);
            if (onePassSignature != null) {
                onePassSignature.init(new BcPGPContentVerifierBuilderProvider(), publicKey);
            }

            int len = 0;
            byte[] buf = new byte[BUFFER_SIZE];
            while ((len = literalDataIn.read(buf, 0, buf.length)) >= 0) {
                if (onePassSignature != null) {
                    onePassSignature.update(buf, 0, len);
                }

                plainOut.write(buf, 0, len);
            }

            if (onePassSignature != null) {
                PGPSignatureList p3 = (PGPSignatureList) pgpFact.nextObject();
                PGPSignature signature = p3.get(0);
                if (!onePassSignature.verify(signature))
                    throw new PGPException("Signature invalid.");
            }

            plainOut.close();
        } else {
            throw new PGPException("message is not a simple encrypted file - type unknown." + message);
        }

        if (!publicKeyEncryptedData.isIntegrityProtected())
            throw new IllegalStateException("Message is not integrity protected.");

        if (!publicKeyEncryptedData.verify())
            throw new IllegalStateException("Message is integrity protected but integrity check failed.");
    } catch (NoSuchProviderException ex) {
        throw new PGPException("Decryption failed.", ex);
    } finally {
        IOUtils.closeQuietly(encryptedIn);
        IOUtils.closeQuietly(privateKeyIn);
        IOUtils.closeQuietly(publicKeyIn);
        IOUtils.closeQuietly(plainOut);
    }
}

From source file:com.geekcommune.identity.EncryptionUtil.java

License:Open Source License

/**
 * Check a one-pass signature/*w  ww.jav a  2 s.c  om*/
 */
private boolean checkOnePassSignature(OutputStream out, PGPOnePassSignatureList p1, PGPObjectFactory pgpFact,
        PGPPublicKeyRingCollection pgpRing) throws PGPException {
    try {
        PGPOnePassSignature ops = null;
        PGPPublicKey key = null;

        int count = 0;
        while (count < p1.size()) {
            ops = p1.get(count);
            key = pgpRing.getPublicKey(ops.getKeyID());
            if (key != null) {
                break;
            }

            count++;
        }

        if (key == null) {
            throw new PGPException("Corresponding public key not found");
        }

        if (key.isRevoked()) {
            String keyId = Long.toHexString(key.getKeyID()).substring(8);
            System.out.println("Warning: Signing key (0x" + keyId + ") has been revoked");
            // throw new PGPException("Signing key (0x"+keyId+") has been revoked");
        }

        PGPLiteralData ld = (PGPLiteralData) pgpFact.nextObject();

        //            if (outputFilename == null) {
        //                outputFilename = ld.getFileName();
        //            }
        //
        //            FileOutputStream out = new FileOutputStream(outputFilename);

        InputStream dataIn = ld.getInputStream();

        ops.initVerify(key, "BC");

        int ch;
        while ((ch = dataIn.read()) >= 0) {
            ops.update((byte) ch);
            out.write(ch);
        }

        out.close();

        PGPSignatureList p3 = (PGPSignatureList) pgpFact.nextObject();

        return ops.verify(p3.get(0));
    } catch (PGPException e) {
        throw e;
    } catch (Exception e) {
        throw new PGPException("Error in verification", e);
    }
}

From source file:com.goodvikings.cryptim.api.KeyRing.java

License:BEER-WARE LICENSE

public boolean decryptVerifyMessage(InputStream in, OutputStream out, String jid)
        throws IOException, PGPException, SignatureException {
    in = new ArmoredInputStream(in);

    PGPObjectFactory plainFact = new PGPObjectFactory(
            ((PGPPublicKeyEncryptedData) ((PGPEncryptedDataList) new PGPObjectFactory(in).nextObject())
                    .getEncryptedDataObjects().next())
                            .getDataStream(new JcePublicKeyDataDecryptorFactoryBuilder().setProvider(PROVIDER)
                                    .build(kp.getPrivateKey())));

    PGPOnePassSignatureList onePassSignatureList = null;
    PGPSignatureList signatureList = null;
    PGPCompressedData compressedData = null;

    Object obj = plainFact.nextObject();
    ByteArrayOutputStream actualOutput = new ByteArrayOutputStream();

    while (obj != null) {
        if (obj instanceof PGPCompressedData) {
            compressedData = (PGPCompressedData) obj;
            plainFact = new PGPObjectFactory(compressedData.getDataStream());
            obj = plainFact.nextObject();
        }/*from   w  w  w.j a v  a 2s .c om*/
        if (obj instanceof PGPLiteralData) {
            Streams.pipeAll(((PGPLiteralData) obj).getInputStream(), actualOutput);
        } else if (obj instanceof PGPOnePassSignatureList) {
            onePassSignatureList = (PGPOnePassSignatureList) obj;
        } else if (obj instanceof PGPSignatureList) {
            signatureList = (PGPSignatureList) obj;
        } else {
            throw new PGPException("message unknown message type.");
        }
        obj = plainFact.nextObject();
    }

    actualOutput.close();
    byte[] output = actualOutput.toByteArray();

    PGPOnePassSignature ops = onePassSignatureList.get(0);
    ops.init(new JcaPGPContentVerifierBuilderProvider().setProvider(PROVIDER), keys.get(jid));
    ops.update(output);

    out.write(output);
    out.flush();
    out.close();

    return ops.verify(signatureList.get(0));
}

From source file:com.google.e2e.bcdriver.Decryptor.java

License:Apache License

private static final Result verifySignedContent(InputStream inp, KeyChecker.PKR verify)
        throws IOException, PGPException, SignatureException {
    PGPObjectFactory plainFact = new PGPObjectFactory(inp, new BcKeyFingerprintCalculator());

    Object msg = plainFact.nextObject();

    // swap in uncompressed data if necessary
    if (msg instanceof PGPCompressedData) {
        PGPCompressedData cData = (PGPCompressedData) msg;
        plainFact = new PGPObjectFactory(cData.getDataStream(), new BcKeyFingerprintCalculator());
        msg = plainFact.nextObject();/*from  w w  w .  j a v a2  s . c  o m*/
    }

    PGPOnePassSignatureList onePassSigList;
    PGPLiteralData lData;
    if (msg instanceof PGPOnePassSignatureList) {
        onePassSigList = (PGPOnePassSignatureList) msg;
        lData = (PGPLiteralData) plainFact.nextObject();
    } else {
        onePassSigList = null;
        lData = (PGPLiteralData) msg;
    }

    if ((verify != null) && (onePassSigList == null)) {
        throw new IOException("Message is unsigned");
    }

    PGPOnePassSignature onePassSig = null;
    int onePassStartIndex = -1;
    PGPPublicKey verifyKey = null;
    if (verify != null) {
        for (int i = 0; i < onePassSigList.size(); i++) {
            List<PGPPublicKey> candidates = verify.getSigningKeysByKeyID(onePassSigList.get(i).getKeyID());
            if (candidates.size() == 1) {
                onePassSig = onePassSigList.get(i);
                onePassStartIndex = i;
                verifyKey = candidates.get(0);
                break;
            }
        }
    }

    if ((verify != null) && (onePassSig == null)) {
        throw new IOException("Failed to find a signature from verifying key");
    }

    if (onePassSig != null) {
        onePassSig.init(new BcPGPContentVerifierBuilderProvider(), verifyKey);
    }
    ByteArrayOutputStream baout = new ByteArrayOutputStream();
    InputStream lin = lData.getInputStream();
    byte buf[] = new byte[8192];
    int nread;
    while ((nread = lin.read(buf)) > 0) {
        baout.write(buf, 0, nread);
        if (onePassSig != null) {
            onePassSig.update(buf, 0, nread);
        }
    }
    baout.close();
    if (onePassSig != null) {
        PGPSignatureList sigList = (PGPSignatureList) plainFact.nextObject();
        // One pass signature trailers occur in LIFO order compared to their
        // location in the header.
        PGPSignature sig = sigList.get(sigList.size() - 1 - onePassStartIndex);
        if (!onePassSig.verify(sig)) {
            throw new IOException("Invalid signature in message");
        }
    }
    return new Result(baout.toByteArray(), lData.getFileName());
}

From source file:com.verhas.licensor.License.java

License:Open Source License

/**
 * Open an encoded license from input stream and decode and load it. If the
 * file can not be loaded or is not signed properly then the method {@see
 * #isVerified()} will return false.//from www .j a v  a 2  s.  c om
 * <p>
 * Otherwise the license will be loaded and can be used.
 * 
 * @param in
 * @throws IOException
 * @throws PGPException
 */
public void setLicenseEncoded(InputStream in) throws IOException, PGPException {
    final ByteArrayInputStream keyIn = new ByteArrayInputStream(publicKeyRing);
    in = PGPUtil.getDecoderStream(in);

    PGPObjectFactory pgpFact = new PGPObjectFactory(in);
    final PGPCompressedData c1 = (PGPCompressedData) pgpFact.nextObject();
    pgpAssertNotNull(c1);
    pgpFact = new PGPObjectFactory(c1.getDataStream());
    final PGPOnePassSignatureList p1 = (PGPOnePassSignatureList) pgpFact.nextObject();

    pgpAssertNotNull(p1);
    final PGPOnePassSignature ops = p1.get(0);
    final PGPLiteralData p2 = (PGPLiteralData) pgpFact.nextObject();

    pgpAssertNotNull(p2);
    final InputStream dIn = p2.getInputStream();
    pgpAssertNotNull(dIn);
    int ch;
    final PGPPublicKeyRingCollection pgpRing = new PGPPublicKeyRingCollection(PGPUtil.getDecoderStream(keyIn));
    pgpAssertNotNull(ops);
    decodeKeyId = ops.getKeyID();
    if (decodeKeyId == null) {
        // there is no key in the key ring that can decode the license
        verified = false;
        licenseProperties = null;
    } else {
        final PGPPublicKey decodeKey = pgpRing.getPublicKey(decodeKeyId);
        final ByteArrayOutputStream out = new ByteArrayOutputStream();
        try {
            ops.initVerify(decodeKey, "BC");
            while ((ch = dIn.read()) >= 0) {
                ops.update((byte) ch);
                out.write(ch);
            }
            final PGPSignatureList p3 = (PGPSignatureList) pgpFact.nextObject();

            if (ops.verify(p3.get(0))) {
                setLicense(new String(out.toByteArray()));
                verified = true;
            } else {
                verified = false;
                licenseProperties = null;
            }
        } catch (final Exception e) {
            verified = false;
            licenseProperties = null;
        }
    }
}

From source file:crypttools.PGPCryptoBC.java

License:Open Source License

public boolean validateData(String data, String publicKey) throws Exception {
    Security.addProvider(new BouncyCastleProvider());
    File fileToVerify = File.createTempFile("temp", ".privateScrap");
    FileUtils.writeStringToFile(fileToVerify, data);

    File publicKeyFile = File.createTempFile("temp", ".publicScrap");
    // Creates an exception
    //        System.out.println(this.armoredPublicKey);
    //        String armoredKeyString = getPublicKey();
    //        System.out.println(armoredKeyString);
    FileUtils.writeStringToFile(publicKeyFile, publicKey);
    //FileUtils.writeStringToFile(publicKeyFile, new String(this.armoredPublicKey, "UTF-8"));

    try {//from   ww w  .j  a v a  2 s. com
        InputStream in = PGPUtil.getDecoderStream(new FileInputStream(fileToVerify));

        PGPObjectFactory pgpObjFactory = new PGPObjectFactory(in);
        PGPCompressedData compressedData = (PGPCompressedData) pgpObjFactory.nextObject();

        //Get the signature from the file

        pgpObjFactory = new PGPObjectFactory(compressedData.getDataStream());
        PGPOnePassSignatureList onePassSignatureList = (PGPOnePassSignatureList) pgpObjFactory.nextObject();
        PGPOnePassSignature onePassSignature = onePassSignatureList.get(0);

        //Get the literal data from the file

        PGPLiteralData pgpLiteralData = (PGPLiteralData) pgpObjFactory.nextObject();
        InputStream literalDataStream = pgpLiteralData.getInputStream();

        InputStream keyIn = new FileInputStream(publicKeyFile);
        PGPPublicKeyRingCollection pgpRing = new PGPPublicKeyRingCollection(PGPUtil.getDecoderStream(keyIn));
        PGPPublicKey key = pgpRing.getPublicKey(onePassSignature.getKeyID());

        FileOutputStream literalDataOutputStream = new FileOutputStream(pgpLiteralData.getFileName());
        onePassSignature.init(new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), key);

        int ch;
        while ((ch = literalDataStream.read()) >= 0) {
            onePassSignature.update((byte) ch);
            literalDataOutputStream.write(ch);
        }

        literalDataOutputStream.close();

        //Get the signature from the written out file

        PGPSignatureList p3 = (PGPSignatureList) pgpObjFactory.nextObject();
        PGPSignature signature = p3.get(0);

        //Verify the two signatures
        boolean valid = onePassSignature.verify(signature);
        return valid;
    } catch (Exception e) {
        System.out.println("Got an Exception: " + e.getMessage());
        return false;
        //do something clever with the exception
    } finally {
        fileToVerify.delete();
        publicKeyFile.delete();
    }
}

From source file:eu.mrbussy.security.crypto.pgp.PGPDecryptor.java

License:Open Source License

public InputStream decryptFile(InputStream in) throws Exception {
    InputStream is = null;//from   www .  ja  v a 2s  .c o m
    byte[] bytes = null;
    InputStream keyIn = new FileInputStream(new File(privateKeyFilePath));
    char[] passwd = password.toCharArray();
    in = PGPUtil.getDecoderStream(in);

    PGPObjectFactory pgpF = new PGPObjectFactory(in);
    PGPEncryptedDataList enc;
    Object o = pgpF.nextObject();
    //
    // the first object might be a PGP marker packet.
    //
    if (o instanceof PGPEncryptedDataList) {
        enc = (PGPEncryptedDataList) o;
    } else {
        enc = (PGPEncryptedDataList) pgpF.nextObject();
    }

    //
    // find the secret key
    //
    Iterator<PGPPublicKeyEncryptedData> it = enc.getEncryptedDataObjects();
    PGPPrivateKey sKey = null;
    PGPPublicKeyEncryptedData pbe = null;
    while (sKey == null && it.hasNext()) {
        pbe = it.next();
        sKey = PGPUtils.findPrivateKey(keyIn, pbe.getKeyID(), passwd);
    }

    if (sKey == null) {
        throw new IllegalArgumentException("secret key for message not found.");
    }

    InputStream clear = pbe.getDataStream(sKey, "BC");
    PGPObjectFactory plainFact = new PGPObjectFactory(clear);
    Object message = plainFact.nextObject();
    PGPObjectFactory pgpFact = null;
    if (message instanceof PGPCompressedData) {
        PGPCompressedData cData = (PGPCompressedData) message;
        pgpFact = new PGPObjectFactory(cData.getDataStream());
        message = pgpFact.nextObject();
    }

    PGPOnePassSignature ops = null;
    if (message instanceof PGPOnePassSignatureList) {
        if (isSigned) {
            PGPOnePassSignatureList p1 = (PGPOnePassSignatureList) message;
            ops = p1.get(0);
            long keyId = ops.getKeyID();
            PGPPublicKey signerPublicKey = PGPUtils.readPublicKey(signingPublicKeyFilePath, keyId);
            ops.initVerify(signerPublicKey, "BC");
        }
        message = pgpFact.nextObject();
    }

    if (message instanceof PGPLiteralData) {
        PGPLiteralData ld = (PGPLiteralData) message;
        if (pbe.isIntegrityProtected()) {
            if (!pbe.verify()) {
                throw new PGPException("message failed integrity check");
            }
        }
        is = ld.getInputStream();
        bytes = IOUtils.toByteArray(is);

        if (isSigned) {
            ops.update(bytes);
            PGPSignatureList p3 = (PGPSignatureList) pgpFact.nextObject();
            if (!ops.verify(p3.get(0))) {
                throw new PGPException("Signature verification failed!");
            }
        }
    } else {
        throw new PGPException("message is not a simple encrypted file - type unknown.");
    }
    return new ByteArrayInputStream(bytes);
}

From source file:google.registry.rde.BouncyCastleTest.java

License:Open Source License

@Test
public void testSignVerify_OnePass() throws Exception {
    // Load the keys.
    PGPPublicKeyRing publicKeyRing = new BcPGPPublicKeyRing(PUBLIC_KEY);
    PGPSecretKeyRing privateKeyRing = new BcPGPSecretKeyRing(PRIVATE_KEY);
    PGPPublicKey publicKey = publicKeyRing.getPublicKey();
    PGPPrivateKey privateKey = extractPrivateKey(privateKeyRing.getSecretKey());

    // Sign the data and write signature data to "signatureFile".
    PGPSignatureGenerator signer = new PGPSignatureGenerator(
            new BcPGPContentSignerBuilder(RSA_GENERAL, SHA256));
    signer.init(PGPSignature.BINARY_DOCUMENT, privateKey);
    addUserInfoToSignature(publicKey, signer);
    ByteArrayOutputStream output = new ByteArrayOutputStream();
    signer.generateOnePassVersion(false).encode(output);
    signer.update(FALL_OF_HYPERION_A_DREAM.getBytes(UTF_8));
    signer.generate().encode(output);//from  www . j  a v  a 2  s  .  co m
    byte[] signatureFileData = output.toByteArray();
    logger.info(".sig file data: " + dumpHex(signatureFileData));

    // Load algorithm information and signature data from "signatureFileData".
    PGPSignature sig;
    PGPOnePassSignature onePass;
    try (ByteArrayInputStream input = new ByteArrayInputStream(signatureFileData)) {
        PGPObjectFactory pgpFact = new BcPGPObjectFactory(input);
        PGPOnePassSignatureList onePassList = (PGPOnePassSignatureList) pgpFact.nextObject();
        PGPSignatureList sigList = (PGPSignatureList) pgpFact.nextObject();
        assertThat(onePassList.size()).isEqualTo(1);
        assertThat(sigList.size()).isEqualTo(1);
        onePass = onePassList.get(0);
        sig = sigList.get(0);
    }

    // Use "onePass" and "sig" to verify "publicKey" signed the text.
    onePass.init(new BcPGPContentVerifierBuilderProvider(), publicKey);
    onePass.update(FALL_OF_HYPERION_A_DREAM.getBytes(UTF_8));
    assertThat(onePass.verify(sig)).isTrue();

    // Verify that they DIDN'T sign the text "hello monster".
    onePass.init(new BcPGPContentVerifierBuilderProvider(), publicKey);
    onePass.update("hello monster".getBytes(UTF_8));
    assertThat(onePass.verify(sig)).isFalse();
}

From source file:org.apache.camel.converter.crypto.PGPDataFormat.java

License:Apache License

protected PGPOnePassSignature getSignature(Exchange exchange, PGPOnePassSignatureList signatureList)
        throws IOException, PGPException, NoSuchProviderException {

    for (int i = 0; i < signatureList.size(); i++) {
        PGPOnePassSignature signature = signatureList.get(i);
        // Determine public key from signature keyId
        PGPPublicKey sigPublicKey = PGPDataFormatUtil.findPublicKeyWithKeyId(exchange.getContext(),
                findSignatureKeyFileName(exchange), findSignatureKeyRing(exchange), signature.getKeyID(),
                false);//w w w.ja  va  2  s  . c  o  m
        if (sigPublicKey == null) {
            continue;
        }
        // choose that signature for which a public key exists!
        signature.init(new JcaPGPContentVerifierBuilderProvider().setProvider(getProvider()), sigPublicKey);
        return signature;
    }
    if (signatureList.isEmpty()) {
        return null;
    } else {
        throw new IllegalArgumentException(
                "No public key found fitting to the signature key Id; cannot verify the signature");
    }

}