Search in sources :

Example 1 with ValidationResult

use of org.xipki.common.qa.ValidationResult in project xipki by xipki.

the class BatchOcspQaStatusCmd method processOcspQuery.

private ValidationResult processOcspQuery(OcspQa ocspQa, BigInteger serialNumber, OcspCertStatus status, Date revTime, File messageDir, File detailsDir, URL serverUrl, X509Certificate respIssuer, X509Certificate issuerCert, IssuerHash issuerHash, RequestOptions requestOptions) throws Exception {
    if (unknownAsGood && status == OcspCertStatus.unknown) {
        status = OcspCertStatus.good;
    }
    RequestResponseDebug debug = null;
    if (saveReq || saveResp) {
        debug = new RequestResponseDebug(saveReq, saveResp);
    }
    OCSPResp response;
    try {
        response = requestor.ask(issuerCert, serialNumber, serverUrl, requestOptions, debug);
    } finally {
        if (debug != null && debug.size() > 0) {
            RequestResponsePair reqResp = debug.get(0);
            String filename = serialNumber.toString(16);
            if (saveReq) {
                byte[] bytes = reqResp.getRequest();
                if (bytes != null) {
                    IoUtil.save(new File(messageDir, filename + FILE_SEP + "request.der"), bytes);
                }
            }
            if (saveResp) {
                byte[] bytes = reqResp.getResponse();
                if (bytes != null) {
                    IoUtil.save(new File(messageDir, filename + FILE_SEP + "response.der"), bytes);
                }
            }
        }
    // end if
    }
    // end finally
    // analyze the result
    OcspResponseOption responseOption = new OcspResponseOption();
    responseOption.setNextUpdateOccurrence(expectedNextUpdateOccurrence);
    responseOption.setCerthashOccurrence(expectedCerthashOccurrence);
    responseOption.setNonceOccurrence(expectedNonceOccurrence);
    responseOption.setRespIssuer(respIssuer);
    responseOption.setSignatureAlgName(sigAlg);
    if (isNotBlank(certhashAlg)) {
        responseOption.setCerthashAlgId(AlgorithmUtil.getHashAlg(certhashAlg));
    }
    ValidationResult ret = ocspQa.checkOcsp(response, issuerHash, serialNumber, null, null, status, responseOption, revTime, noSigVerify.booleanValue());
    String validity = ret.isAllSuccessful() ? "valid" : "invalid";
    String hexSerial = serialNumber.toString(16);
    StringBuilder sb = new StringBuilder(50);
    sb.append("OCSP response for ").append(serialNumber).append(" (0x").append(hexSerial).append(") is ").append(validity);
    for (ValidationIssue issue : ret.getValidationIssues()) {
        sb.append("\n");
        OcspQaStatusCmd.format(issue, "    ", sb);
    }
    IoUtil.save(new File(detailsDir, hexSerial + "." + validity), sb.toString().getBytes());
    return ret;
}
Also used : RequestResponsePair(org.xipki.common.RequestResponsePair) RequestResponseDebug(org.xipki.common.RequestResponseDebug) OcspResponseOption(org.xipki.ocsp.qa.OcspResponseOption) ValidationResult(org.xipki.common.qa.ValidationResult) File(java.io.File) ValidationIssue(org.xipki.common.qa.ValidationIssue) OCSPResp(org.bouncycastle.cert.ocsp.OCSPResp)

Example 2 with ValidationResult

use of org.xipki.common.qa.ValidationResult in project xipki by xipki.

the class OcspQaStatusCmd method processResponse.

// method checkParameters
@Override
protected Object processResponse(OCSPResp response, X509Certificate respIssuer, IssuerHash issuerHash, List<BigInteger> serialNumbers, Map<BigInteger, byte[]> encodedCerts) throws Exception {
    OcspResponseOption responseOption = new OcspResponseOption();
    responseOption.setNextUpdateOccurrence(expectedNextUpdateOccurrence);
    responseOption.setCerthashOccurrence(expectedCerthashOccurrence);
    responseOption.setNonceOccurrence(expectedNonceOccurrence);
    responseOption.setRespIssuer(respIssuer);
    responseOption.setSignatureAlgName(sigAlg);
    if (isNotBlank(certhashAlg)) {
        responseOption.setCerthashAlgId(AlgorithmUtil.getHashAlg(certhashAlg));
    }
    if (ocspQa == null) {
        ocspQa = new OcspQa(securityFactory);
    }
    ValidationResult result = ocspQa.checkOcsp(response, issuerHash, serialNumbers, encodedCerts, expectedOcspError, expectedStatuses, expecteRevTimes, responseOption, noSigVerify);
    StringBuilder sb = new StringBuilder(50);
    sb.append("OCSP response is ");
    String txt = result.isAllSuccessful() ? "valid" : "invalid";
    sb.append(txt);
    if (verbose.booleanValue()) {
        for (ValidationIssue issue : result.getValidationIssues()) {
            sb.append("\n");
            format(issue, "    ", sb);
        }
    }
    println(sb.toString());
    if (!result.isAllSuccessful()) {
        throw new CmdFailure("OCSP response is invalid");
    }
    return null;
}
Also used : OcspQa(org.xipki.ocsp.qa.OcspQa) CmdFailure(org.xipki.console.karaf.CmdFailure) OcspResponseOption(org.xipki.ocsp.qa.OcspResponseOption) ValidationResult(org.xipki.common.qa.ValidationResult) ValidationIssue(org.xipki.common.qa.ValidationIssue)

Example 3 with ValidationResult

use of org.xipki.common.qa.ValidationResult in project xipki by xipki.

the class CheckCertCmd method execute0.

@Override
protected Object execute0() throws Exception {
    Set<String> issuerNames = qaSystemManager.getIssuerNames();
    if (isEmpty(issuerNames)) {
        throw new IllegalCmdParamException("no issuer is configured");
    }
    if (issuerName == null) {
        if (issuerNames.size() != 1) {
            throw new IllegalCmdParamException("no issuer is specified");
        }
        issuerName = issuerNames.iterator().next();
    }
    if (!issuerNames.contains(issuerName)) {
        throw new IllegalCmdParamException("issuer " + issuerName + " is not within the configured issuers " + issuerNames);
    }
    X509IssuerInfo issuerInfo = qaSystemManager.getIssuer(issuerName);
    X509CertprofileQa qa = qaSystemManager.getCertprofile(profileName);
    if (qa == null) {
        throw new IllegalCmdParamException("found no certificate profile named '" + profileName + "'");
    }
    CertificationRequest csr = CertificationRequest.getInstance(IoUtil.read(csrFile));
    Extensions extensions = null;
    CertificationRequestInfo reqInfo = csr.getCertificationRequestInfo();
    ASN1Set attrs = reqInfo.getAttributes();
    for (int i = 0; i < attrs.size(); i++) {
        Attribute attr = Attribute.getInstance(attrs.getObjectAt(i));
        if (PKCSObjectIdentifiers.pkcs_9_at_extensionRequest.equals(attr.getAttrType())) {
            extensions = Extensions.getInstance(attr.getAttributeValues()[0]);
        }
    }
    byte[] certBytes = IoUtil.read(certFile);
    ValidationResult result = qa.checkCert(certBytes, issuerInfo, reqInfo.getSubject(), reqInfo.getSubjectPublicKeyInfo(), extensions);
    StringBuilder sb = new StringBuilder();
    sb.append(certFile).append(" (certprofile ").append(profileName).append(")\n");
    sb.append("\tcertificate is ");
    sb.append(result.isAllSuccessful() ? "valid" : "invalid");
    if (verbose.booleanValue()) {
        for (ValidationIssue issue : result.getValidationIssues()) {
            sb.append("\n");
            format(issue, "    ", sb);
        }
    }
    println(sb.toString());
    if (!result.isAllSuccessful()) {
        throw new CmdFailure("certificate is invalid");
    }
    return null;
}
Also used : X509CertprofileQa(org.xipki.ca.qa.X509CertprofileQa) CertificationRequestInfo(org.bouncycastle.asn1.pkcs.CertificationRequestInfo) Attribute(org.bouncycastle.asn1.pkcs.Attribute) X509IssuerInfo(org.xipki.ca.qa.X509IssuerInfo) Extensions(org.bouncycastle.asn1.x509.Extensions) ValidationResult(org.xipki.common.qa.ValidationResult) ValidationIssue(org.xipki.common.qa.ValidationIssue) ASN1Set(org.bouncycastle.asn1.ASN1Set) CmdFailure(org.xipki.console.karaf.CmdFailure) IllegalCmdParamException(org.xipki.console.karaf.IllegalCmdParamException) CertificationRequest(org.bouncycastle.asn1.pkcs.CertificationRequest)

Example 4 with ValidationResult

use of org.xipki.common.qa.ValidationResult in project xipki by xipki.

the class OcspQa method checkOcsp.

public ValidationResult checkOcsp(OCSPResp response, IssuerHash issuerHash, List<BigInteger> serialNumbers, Map<BigInteger, byte[]> encodedCerts, OcspError expectedOcspError, Map<BigInteger, OcspCertStatus> expectedOcspStatuses, Map<BigInteger, Date> expectedRevTimes, OcspResponseOption responseOption, boolean noSigVerify) {
    ParamUtil.requireNonNull("response", response);
    ParamUtil.requireNonEmpty("serialNumbers", serialNumbers);
    ParamUtil.requireNonEmpty("expectedOcspStatuses", expectedOcspStatuses);
    ParamUtil.requireNonNull("responseOption", responseOption);
    List<ValidationIssue> resultIssues = new LinkedList<ValidationIssue>();
    int status = response.getStatus();
    // Response status
    ValidationIssue issue = new ValidationIssue("OCSP.STATUS", "response.status");
    resultIssues.add(issue);
    if (expectedOcspError != null) {
        if (status != expectedOcspError.getStatus()) {
            issue.setFailureMessage("is '" + status + "', but expected '" + expectedOcspError.getStatus() + "'");
        }
    } else {
        if (status != 0) {
            issue.setFailureMessage("is '" + status + "', but expected '0'");
        }
    }
    if (status != 0) {
        return new ValidationResult(resultIssues);
    }
    ValidationIssue encodingIssue = new ValidationIssue("OCSP.ENCODING", "response encoding");
    resultIssues.add(encodingIssue);
    BasicOCSPResp basicResp;
    try {
        basicResp = (BasicOCSPResp) response.getResponseObject();
    } catch (OCSPException ex) {
        encodingIssue.setFailureMessage(ex.getMessage());
        return new ValidationResult(resultIssues);
    }
    SingleResp[] singleResponses = basicResp.getResponses();
    issue = new ValidationIssue("OCSP.RESPONSES.NUM", "number of single responses");
    resultIssues.add(issue);
    if (singleResponses == null || singleResponses.length == 0) {
        issue.setFailureMessage("received no status from server");
        return new ValidationResult(resultIssues);
    }
    final int n = singleResponses.length;
    if (n != serialNumbers.size()) {
        issue.setFailureMessage("is '" + n + "', but expected '" + serialNumbers.size() + "'");
        return new ValidationResult(resultIssues);
    }
    boolean hasSignature = basicResp.getSignature() != null;
    // check the signature if available
    if (noSigVerify) {
        issue = new ValidationIssue("OCSP.SIG", (hasSignature ? "signature presence (Ignore)" : "signature presence"));
    } else {
        issue = new ValidationIssue("OCSP.SIG", "signature presence");
    }
    resultIssues.add(issue);
    if (!hasSignature) {
        issue.setFailureMessage("response is not signed");
    }
    if (hasSignature & !noSigVerify) {
        // signature algorithm
        issue = new ValidationIssue("OCSP.SIG.ALG", "signature algorithm");
        resultIssues.add(issue);
        String expectedSigalgo = responseOption.getSignatureAlgName();
        if (expectedSigalgo != null) {
            AlgorithmIdentifier sigAlg = basicResp.getSignatureAlgorithmID();
            try {
                String sigAlgName = AlgorithmUtil.getSignatureAlgoName(sigAlg);
                if (!AlgorithmUtil.equalsAlgoName(sigAlgName, expectedSigalgo)) {
                    issue.setFailureMessage("is '" + sigAlgName + "', but expected '" + expectedSigalgo + "'");
                }
            } catch (NoSuchAlgorithmException ex) {
                issue.setFailureMessage("could not extract the signature algorithm");
            }
        }
        // end if (expectedSigalgo != null)
        // signer certificate
        ValidationIssue sigSignerCertIssue = new ValidationIssue("OCSP.SIGNERCERT", "signer certificate");
        resultIssues.add(sigSignerCertIssue);
        // signature validation
        ValidationIssue sigValIssue = new ValidationIssue("OCSP.SIG.VALIDATION", "signature validation");
        resultIssues.add(sigValIssue);
        X509CertificateHolder respSigner = null;
        X509CertificateHolder[] responderCerts = basicResp.getCerts();
        if (responderCerts == null || responderCerts.length < 1) {
            sigSignerCertIssue.setFailureMessage("no responder certificate is contained in the response");
            sigValIssue.setFailureMessage("could not find certificate to validate signature");
        } else {
            ResponderID respId = basicResp.getResponderId().toASN1Primitive();
            X500Name respIdByName = respId.getName();
            byte[] respIdByKey = respId.getKeyHash();
            for (X509CertificateHolder cert : responderCerts) {
                if (respIdByName != null) {
                    if (cert.getSubject().equals(respIdByName)) {
                        respSigner = cert;
                    }
                } else {
                    byte[] spkiSha1 = HashAlgo.SHA1.hash(cert.getSubjectPublicKeyInfo().getPublicKeyData().getBytes());
                    if (Arrays.equals(respIdByKey, spkiSha1)) {
                        respSigner = cert;
                    }
                }
                if (respSigner != null) {
                    break;
                }
            }
            if (respSigner == null) {
                sigSignerCertIssue.setFailureMessage("no responder certificate match the ResponderId");
                sigValIssue.setFailureMessage("could not find certificate matching the" + " ResponderId to validate signature");
            }
        }
        if (respSigner != null) {
            issue = new ValidationIssue("OCSP.SIGNERCERT.TRUST", "signer certificate validation");
            resultIssues.add(issue);
            for (int i = 0; i < singleResponses.length; i++) {
                SingleResp singleResp = singleResponses[i];
                if (!respSigner.isValidOn(singleResp.getThisUpdate())) {
                    issue.setFailureMessage(String.format("responder certificate is not valid on the thisUpdate[%d]: %s", i, singleResp.getThisUpdate()));
                }
            }
            // end for
            X509Certificate respIssuer = responseOption.getRespIssuer();
            if (!issue.isFailed() && respIssuer != null) {
                X509Certificate jceRespSigner;
                try {
                    jceRespSigner = X509Util.toX509Cert(respSigner.toASN1Structure());
                    if (X509Util.issues(respIssuer, jceRespSigner)) {
                        jceRespSigner.verify(respIssuer.getPublicKey());
                    } else {
                        issue.setFailureMessage("responder signer is not trusted");
                    }
                } catch (Exception ex) {
                    issue.setFailureMessage("responder signer is not trusted");
                }
            }
            try {
                PublicKey responderPubKey = KeyUtil.generatePublicKey(respSigner.getSubjectPublicKeyInfo());
                ContentVerifierProvider cvp = securityFactory.getContentVerifierProvider(responderPubKey);
                boolean sigValid = basicResp.isSignatureValid(cvp);
                if (!sigValid) {
                    sigValIssue.setFailureMessage("signature is invalid");
                }
            } catch (Exception ex) {
                sigValIssue.setFailureMessage("could not validate signature");
            }
        }
    // end if
    }
    // end if (hasSignature)
    // nonce
    Extension nonceExtn = basicResp.getExtension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce);
    resultIssues.add(checkOccurrence("OCSP.NONCE", nonceExtn, responseOption.getNonceOccurrence()));
    boolean extendedRevoke = basicResp.getExtension(ObjectIdentifiers.id_pkix_ocsp_extendedRevoke) != null;
    for (int i = 0; i < singleResponses.length; i++) {
        SingleResp singleResp = singleResponses[i];
        BigInteger serialNumber = singleResp.getCertID().getSerialNumber();
        OcspCertStatus expectedStatus = expectedOcspStatuses.get(serialNumber);
        Date expectedRevTime = null;
        if (expectedRevTimes != null) {
            expectedRevTime = expectedRevTimes.get(serialNumber);
        }
        byte[] encodedCert = null;
        if (encodedCerts != null) {
            encodedCert = encodedCerts.get(serialNumber);
        }
        List<ValidationIssue> issues = checkSingleCert(i, singleResp, issuerHash, expectedStatus, encodedCert, expectedRevTime, extendedRevoke, responseOption.getNextUpdateOccurrence(), responseOption.getCerthashOccurrence(), responseOption.getCerthashAlgId());
        resultIssues.addAll(issues);
    }
    return new ValidationResult(resultIssues);
}
Also used : ResponderID(org.bouncycastle.asn1.ocsp.ResponderID) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) X500Name(org.bouncycastle.asn1.x500.X500Name) ValidationResult(org.xipki.common.qa.ValidationResult) AlgorithmIdentifier(org.bouncycastle.asn1.x509.AlgorithmIdentifier) OCSPException(org.bouncycastle.cert.ocsp.OCSPException) SingleResp(org.bouncycastle.cert.ocsp.SingleResp) ContentVerifierProvider(org.bouncycastle.operator.ContentVerifierProvider) PublicKey(java.security.PublicKey) ValidationIssue(org.xipki.common.qa.ValidationIssue) LinkedList(java.util.LinkedList) X509Certificate(java.security.cert.X509Certificate) OCSPException(org.bouncycastle.cert.ocsp.OCSPException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) Date(java.util.Date) Extension(org.bouncycastle.asn1.x509.Extension) BasicOCSPResp(org.bouncycastle.cert.ocsp.BasicOCSPResp) X509CertificateHolder(org.bouncycastle.cert.X509CertificateHolder) BigInteger(java.math.BigInteger)

Example 5 with ValidationResult

use of org.xipki.common.qa.ValidationResult in project xipki by xipki.

the class BatchOcspQaStatusCmd method execute0.

@Override
protected final Object execute0() throws Exception {
    expectedCerthashOccurrence = Occurrence.forName(certhashOccurrenceText);
    expectedNextUpdateOccurrence = Occurrence.forName(nextUpdateOccurrenceText);
    expectedNonceOccurrence = Occurrence.forName(nonceOccurrenceText);
    File outDir = new File(outDirStr);
    File messageDir = new File(outDir, "messages");
    messageDir.mkdirs();
    File detailsDir = new File(outDir, "details");
    detailsDir.mkdirs();
    println("The result is saved in the folder " + outDir.getPath());
    String linuxIssuer = (respIssuerFile != null) ? "-CAfile ../../responder_issuer.pem" : "-no_cert_verify";
    String winIssuer = (respIssuerFile != null) ? "-CAfile ..\\..\\responder_issuer.pem" : "-no_cert_verify";
    String linuxMsg = "openssl ocsp -text ";
    String winMsg = "openssl ocsp -text ";
    String shellFilePath = null;
    if (saveReq && saveResp) {
        linuxMsg += linuxIssuer + " -reqin request.der -respin response.der";
        winMsg += winIssuer + " -reqin request.der -respin response.der";
        shellFilePath = new File(outDir, "verify-req-resp").getPath();
    } else if (saveReq) {
        linuxMsg += "-reqin request.der\n";
        winMsg += "-reqin request.der\n";
        shellFilePath = new File(outDir, "verify-req").getPath();
    } else if (saveResp) {
        linuxMsg += linuxIssuer + " -respin response.der\n";
        winMsg += winIssuer + " -respin response.der\n";
        shellFilePath = new File(outDir, "verify-resp").getPath();
    }
    if (shellFilePath != null) {
        File linuxShellFile = new File(shellFilePath + ".sh");
        IoUtil.save(linuxShellFile, ("#!/bin/sh\n" + linuxMsg).getBytes());
        IoUtil.save(shellFilePath + ".bat", ("@echo off\r\n" + winMsg).getBytes());
        linuxShellFile.setExecutable(true);
    }
    X509Certificate issuerCert = X509Util.parseCert(issuerCertFile);
    X509Certificate respIssuer = null;
    if (respIssuerFile != null) {
        respIssuer = X509Util.parseCert(IoUtil.expandFilepath(respIssuerFile));
        IoUtil.save(new File(outDir, "responder-issuer.pem"), X509Util.toPemCert(respIssuer).getBytes());
    }
    RequestOptions requestOptions = getRequestOptions();
    IssuerHash issuerHash = new IssuerHash(HashAlgo.getNonNullInstance(requestOptions.getHashAlgorithmId()), Certificate.getInstance(issuerCert.getEncoded()));
    OutputStream resultOut = new FileOutputStream(new File(outDir, "overview.txt"));
    BufferedReader snReader = new BufferedReader(new FileReader(snFile));
    int numSucc = 0;
    int numFail = 0;
    try {
        URL serverUrl = new URL(serverUrlStr);
        OcspQa ocspQa = new OcspQa(securityFactory);
        // Content of a line:
        // <hex-encoded serial number>[,<reason code>,<revocation time in epoch seconds>]
        int lineNo = 0;
        String line;
        while ((line = snReader.readLine()) != null) {
            lineNo++;
            line = line.trim();
            if (line.startsWith("#") || line.isEmpty()) {
                resultOut.write(line.getBytes());
                resultOut.write('\n');
                continue;
            }
            String resultText = lineNo + ": " + line + ": ";
            try {
                ValidationResult result = processOcspQuery(ocspQa, line, messageDir, detailsDir, serverUrl, respIssuer, issuerCert, issuerHash, requestOptions);
                if (result.isAllSuccessful()) {
                    numSucc++;
                    resultText += "valid";
                } else {
                    numFail++;
                    resultText += "invalid";
                }
            } catch (Throwable th) {
                LogUtil.error(LOG, th);
                numFail++;
                resultText += "error - " + th.getMessage();
            }
            if (!noout) {
                println(resultText);
            }
            println(resultText, resultOut);
        }
        // unknown serial number
        lineNo++;
        SecureRandom random = new SecureRandom();
        byte[] bytes = new byte[16];
        random.nextBytes(bytes);
        bytes[0] = (byte) (0x7F & bytes[0]);
        BigInteger serialNumber = new BigInteger(bytes);
        String resultText = lineNo + ": " + serialNumber.toString(16) + ",unknown: ";
        try {
            ValidationResult result = processOcspQuery(ocspQa, serialNumber, OcspCertStatus.unknown, null, messageDir, detailsDir, serverUrl, respIssuer, issuerCert, issuerHash, requestOptions);
            if (result.isAllSuccessful()) {
                numSucc++;
                resultText += "valid";
            } else {
                numFail++;
                resultText += "invalid";
            }
        } catch (Throwable th) {
            LogUtil.error(LOG, th);
            numFail++;
            resultText += "error - " + th.getMessage();
        }
        if (!noout) {
            println(resultText);
        }
        println(resultText, resultOut);
        String message = StringUtil.concatObjectsCap(200, "=====BEGIN SUMMARY=====", "\n       url: ", serverUrlStr, "\n       sum: ", numFail + numSucc, "\nsuccessful: ", numSucc, "\n    failed: ", numFail, "\n=====END SUMMARY=====");
        println(message);
        println(message, resultOut);
    } finally {
        snReader.close();
        resultOut.close();
    }
    return null;
}
Also used : RequestOptions(org.xipki.ocsp.client.api.RequestOptions) OutputStream(java.io.OutputStream) FileOutputStream(java.io.FileOutputStream) SecureRandom(java.security.SecureRandom) ValidationResult(org.xipki.common.qa.ValidationResult) X509Certificate(java.security.cert.X509Certificate) URL(java.net.URL) IssuerHash(org.xipki.security.IssuerHash) OcspQa(org.xipki.ocsp.qa.OcspQa) FileOutputStream(java.io.FileOutputStream) BufferedReader(java.io.BufferedReader) BigInteger(java.math.BigInteger) FileReader(java.io.FileReader) File(java.io.File)

Aggregations

ValidationResult (org.xipki.common.qa.ValidationResult)6 ValidationIssue (org.xipki.common.qa.ValidationIssue)5 BigInteger (java.math.BigInteger)3 X509Certificate (java.security.cert.X509Certificate)3 File (java.io.File)2 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)2 Date (java.util.Date)2 LinkedList (java.util.LinkedList)2 AlgorithmIdentifier (org.bouncycastle.asn1.x509.AlgorithmIdentifier)2 CmdFailure (org.xipki.console.karaf.CmdFailure)2 OcspQa (org.xipki.ocsp.qa.OcspQa)2 OcspResponseOption (org.xipki.ocsp.qa.OcspResponseOption)2 BufferedReader (java.io.BufferedReader)1 FileOutputStream (java.io.FileOutputStream)1 FileReader (java.io.FileReader)1 IOException (java.io.IOException)1 OutputStream (java.io.OutputStream)1 URL (java.net.URL)1 PublicKey (java.security.PublicKey)1 SecureRandom (java.security.SecureRandom)1