use of org.xipki.util.Curl.CurlResult 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