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);
}
}
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));
}
Aggregations