Search in sources :

Example 1 with AddPreChainResponse

use of org.xipki.security.ctlog.CtLogMessages.AddPreChainResponse in project xipki by xipki.

the class CtLogServlet method doPost.

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    try {
        AddPreChainRequest req0 = parse(req.getInputStream(), AddPreChainRequest.class);
        List<byte[]> chain = req0.getChain();
        if (chain == null || chain.size() < 2) {
            String msg = "chain has less than two certificates";
            LOG.warn(msg);
            resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
            return;
        }
        Certificate cert = Certificate.getInstance(chain.get(0));
        Certificate caCert = Certificate.getInstance(chain.get(1));
        byte[] issuerKeyHash = HashAlgo.SHA256.hash(caCert.getSubjectPublicKeyInfo().getEncoded());
        byte[] preCertTbsCert = CtLog.getPreCertTbsCert(cert.getTBSCertificate());
        byte sctVersion = 0;
        long timestamp = System.currentTimeMillis();
        byte[] sctExtensions = null;
        Signature sig = Signature.getInstance(signatureAlgo);
        sig.initSign(signingKey);
        CtLog.update(sig, sctVersion, timestamp, sctExtensions, issuerKeyHash, preCertTbsCert);
        byte[] signature = sig.sign();
        AddPreChainResponse resp0 = new AddPreChainResponse();
        resp0.setSct_version(sctVersion);
        resp0.setId(logId);
        resp0.setTimestamp(timestamp);
        DigitallySigned digitallySigned = new DigitallySigned(signatureAndHashAlgorithm, signature);
        resp0.setSignature(digitallySigned.getEncoded());
        byte[] respContent = JSON.toJSONBytes(resp0);
        resp.setContentType("application/json");
        resp.setContentLengthLong(respContent.length);
        resp.getOutputStream().write(respContent);
        resp.setStatus(HttpServletResponse.SC_OK);
    } catch (Exception ex) {
        LogUtil.error(LOG, ex);
        throw new ServletException(ex.getMessage(), ex);
    }
}
Also used : ServletException(javax.servlet.ServletException) DigitallySigned(org.xipki.security.ctlog.CtLog.DigitallySigned) Signature(java.security.Signature) AddPreChainRequest(org.xipki.security.ctlog.CtLogMessages.AddPreChainRequest) AddPreChainResponse(org.xipki.security.ctlog.CtLogMessages.AddPreChainResponse) ServletException(javax.servlet.ServletException) InvalidKeySpecException(java.security.spec.InvalidKeySpecException) IOException(java.io.IOException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) Certificate(org.bouncycastle.asn1.x509.Certificate)

Example 2 with AddPreChainResponse

use of org.xipki.security.ctlog.CtLogMessages.AddPreChainResponse in project xipki by xipki.

the class CtLogClient method getCtLogScts.

// constructor
public SignedCertificateTimestampList getCtLogScts(X509CertificateHolder precert, X509Cert caCert, List<X509Cert> certchain, CtLogPublicKeyFinder publicKeyFinder) throws OperationException {
    AddPreChainRequest request = new AddPreChainRequest();
    List<byte[]> chain = new LinkedList<>();
    request.setChain(chain);
    byte[] encodedPreCert;
    try {
        encodedPreCert = precert.getEncoded();
    } catch (IOException ex) {
        throw new OperationException(ErrorCode.SYSTEM_FAILURE, ex.getMessage());
    }
    byte[] issuerKeyHash;
    try {
        issuerKeyHash = HashAlgo.SHA256.hash(caCert.getSubjectPublicKeyInfo().getEncoded());
    } catch (IOException ex) {
        throw new OperationException(ErrorCode.SYSTEM_FAILURE, ex.getMessage());
    }
    byte[] preCertTbsCert;
    try {
        preCertTbsCert = CtLog.getPreCertTbsCert(precert.toASN1Structure().getTBSCertificate());
    } catch (IOException ex) {
        throw new OperationException(ErrorCode.SYSTEM_FAILURE, ex.getMessage());
    }
    chain.add(encodedPreCert);
    chain.add(caCert.getEncoded());
    if (certchain != null) {
        for (X509Cert m : certchain) {
            chain.add(m.getEncoded());
        }
    }
    byte[] content = JSON.toJSONBytes(request);
    if (LOG.isDebugEnabled()) {
        LOG.debug("CTLog Request: {}", StringUtil.toUtf8String(content));
    }
    List<SignedCertificateTimestamp> scts = new ArrayList<>(addPreChainUrls.size());
    Map<String, String> headers = new HashMap<>();
    headers.put("content-type", "application/json");
    for (String url : addPreChainUrls) {
        CurlResult res;
        try {
            res = curl.curlPost(url, false, headers, null, content);
        } catch (Exception ex) {
            throw new OperationException(ErrorCode.SYSTEM_FAILURE, "error while calling " + url + ": " + ex.getMessage());
        }
        byte[] respContent = res.getContent();
        if (respContent == null) {
            throw new OperationException(ErrorCode.SYSTEM_FAILURE, "server does not return any content while responding " + url);
        }
        if (LOG.isDebugEnabled()) {
            LOG.debug("CTLog Response: {}", StringUtil.toUtf8String(respContent));
        }
        AddPreChainResponse resp = JSON.parseObject(respContent, AddPreChainResponse.class);
        DigitallySigned ds = DigitallySigned.getInstance(resp.getSignature(), new AtomicInteger(0));
        byte sctVersion = resp.getSct_version();
        byte[] logId = resp.getId();
        String hexLogId = Hex.encodeUpper(logId);
        long timestamp = resp.getTimestamp();
        byte[] extensions = resp.getExtensions();
        PublicKey verifyKey = publicKeyFinder == null ? null : publicKeyFinder.getPublicKey(logId);
        if (verifyKey == null) {
            LOG.warn("could not find CtLog public key 0x{} to verify the SCT", hexLogId);
        } else {
            SignatureAndHashAlgorithm algorithm = ds.getAlgorithm();
            String signAlgo = getSignatureAlgo(algorithm);
            boolean sigValid;
            try {
                Signature sig = Signature.getInstance(signAlgo, "BC");
                sig.initVerify(verifyKey);
                CtLog.update(sig, sctVersion, timestamp, extensions, issuerKeyHash, preCertTbsCert);
                sigValid = sig.verify(ds.getSignature());
            } catch (NoSuchAlgorithmException | NoSuchProviderException | InvalidKeyException | SignatureException ex) {
                throw new OperationException(ErrorCode.SYSTEM_FAILURE, "error verifying SCT signature");
            }
            if (sigValid) {
                LOG.info("verified SCT signature with logId {} and timestamp {}", hexLogId, timestamp);
            } else {
                throw new OperationException(ErrorCode.SYSTEM_FAILURE, "SCT signature is invalid");
            }
        }
        SignedCertificateTimestamp sct = new SignedCertificateTimestamp(sctVersion, logId, timestamp, extensions, ds);
        scts.add(sct);
    }
    return new SignedCertificateTimestampList(new SerializedSCT(scts));
}
Also used : CurlResult(org.xipki.util.Curl.CurlResult) X509Cert(org.xipki.security.X509Cert) OperationException(org.xipki.ca.api.OperationException) AddPreChainRequest(org.xipki.security.ctlog.CtLogMessages.AddPreChainRequest) IOException(java.io.IOException) IOException(java.io.IOException) OperationException(org.xipki.ca.api.OperationException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AddPreChainResponse(org.xipki.security.ctlog.CtLogMessages.AddPreChainResponse)

Aggregations

IOException (java.io.IOException)2 AddPreChainRequest (org.xipki.security.ctlog.CtLogMessages.AddPreChainRequest)2 AddPreChainResponse (org.xipki.security.ctlog.CtLogMessages.AddPreChainResponse)2 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)1 Signature (java.security.Signature)1 InvalidKeySpecException (java.security.spec.InvalidKeySpecException)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 ServletException (javax.servlet.ServletException)1 Certificate (org.bouncycastle.asn1.x509.Certificate)1 OperationException (org.xipki.ca.api.OperationException)1 X509Cert (org.xipki.security.X509Cert)1 DigitallySigned (org.xipki.security.ctlog.CtLog.DigitallySigned)1 CurlResult (org.xipki.util.Curl.CurlResult)1