private String getEncodedProtectedHeader(boolean useJwk, String resourceUrl, AcmeAccount account, boolean staging) throws AcmeException { JsonObjectBuilder protectedHeaderBuilder = Json.createObjectBuilder().add(ALG, account.getAlgHeader()); if (useJwk) { protectedHeaderBuilder.add(JWK, getJwk(account.getPublicKey(), account.getAlgHeader())); } else { protectedHeaderBuilder.add(KID, getAccountUrl(account, staging)); } protectedHeaderBuilder .add(NONCE, base64UrlEncode(getNonce(account, staging))) .add(URL, resourceUrl); return getEncodedJson(protectedHeaderBuilder.build()); }
/** * Get the key authorization string for this challenge. * * @param account the ACME account information to use (must not be {@code null}) * @return the key authorization string for this challenge * @throws AcmeException if the key authorization string cannot be determined */ public String getKeyAuthorization(AcmeAccount account) throws AcmeException { Assert.checkNotNullParam("account", account); JsonObject jwk = getJwk(account.getPublicKey(), account.getAlgHeader()); byte[] jwkWithoutWhitespace = CodePointIterator.ofString(jwk.toString()).skip(Character::isWhitespace).skipCrLf().asUtf8().drain(); try { MessageDigest messageDigest = MessageDigest.getInstance("SHA-256"); messageDigest.update(jwkWithoutWhitespace); byte[] jwkThumbprint = messageDigest.digest(); return token + "." + base64UrlEncode(jwkThumbprint); } catch (NoSuchAlgorithmException e) { throw acme.unableToDetermineKeyAuthorizationString(e); } }
/** * Change the key that is associated with the given ACME account. * * @param account the ACME account information to use (must not be {@code null}) * @param staging whether or not the staging server URL should be used * @param certificate the new certificate to associate with the given ACME account (must not be {@code null}) * @param privateKey the new private key to associate with the given ACME account (must not be {@code null}) * @throws AcmeException if an error occurs while attempting to change the key that is associated with the given ACME account */ public void changeAccountKey(AcmeAccount account, boolean staging, X509Certificate certificate, PrivateKey privateKey) throws AcmeException { Assert.checkNotNullParam("account", account); Assert.checkNotNullParam("certificate", certificate); Assert.checkNotNullParam("privateKey", privateKey); final String keyChangeUrl = getResourceUrl(account, AcmeResource.KEY_CHANGE, staging).toString(); final String signatureAlgorithm = getDefaultCompatibleSignatureAlgorithmName(privateKey); final String algHeader = getAlgHeaderFromSignatureAlgorithm(signatureAlgorithm); final String innerEncodedProtectedHeader = getEncodedProtectedHeader(algHeader, certificate.getPublicKey(), keyChangeUrl); JsonObjectBuilder innerPayloadBuilder = Json.createObjectBuilder() .add(ACCOUNT, getAccountUrl(account, staging)) .add(OLD_KEY, getJwk(account.getPublicKey(), account.getAlgHeader())); final String innerEncodedPayload = getEncodedJson(innerPayloadBuilder.build()); final String innerEncodedSignature = getEncodedSignature(privateKey, signatureAlgorithm, innerEncodedProtectedHeader, innerEncodedPayload); final String outerEncodedPayload = getEncodedJson(getJws(innerEncodedProtectedHeader, innerEncodedPayload, innerEncodedSignature)); sendPostRequestWithRetries(account, staging, keyChangeUrl, false, outerEncodedPayload, HttpURLConnection.HTTP_OK); account.changeCertificateAndPrivateKey(certificate, privateKey); // update account info }
private String getEncodedProtectedHeader(boolean useJwk, String resourceUrl, AcmeAccount account, boolean staging) throws AcmeException { JsonObjectBuilder protectedHeaderBuilder = Json.createObjectBuilder().add(ALG, account.getAlgHeader()); if (useJwk) { protectedHeaderBuilder.add(JWK, getJwk(account.getPublicKey(), account.getAlgHeader())); } else { protectedHeaderBuilder.add(KID, getAccountUrl(account, staging)); } protectedHeaderBuilder .add(NONCE, base64UrlEncode(getNonce(account, staging))) .add(URL, resourceUrl); return getEncodedJson(protectedHeaderBuilder.build()); }
private String getEncodedProtectedHeader(boolean useJwk, String resourceUrl, AcmeAccount account, boolean staging) throws AcmeException { JsonObjectBuilder protectedHeaderBuilder = Json.createObjectBuilder().add(ALG, account.getAlgHeader()); if (useJwk) { protectedHeaderBuilder.add(JWK, getJwk(account.getPublicKey(), account.getAlgHeader())); } else { protectedHeaderBuilder.add(KID, getAccountUrl(account, staging)); } protectedHeaderBuilder .add(NONCE, base64UrlEncode(getNonce(account, staging))) .add(URL, resourceUrl); return getEncodedJson(protectedHeaderBuilder.build()); }
private String getEncodedProtectedHeader(boolean useJwk, String resourceUrl, AcmeAccount account, boolean staging) throws AcmeException { JsonObjectBuilder protectedHeaderBuilder = Json.createObjectBuilder().add(ALG, account.getAlgHeader()); if (useJwk) { protectedHeaderBuilder.add(JWK, getJwk(account.getPublicKey(), account.getAlgHeader())); } else { protectedHeaderBuilder.add(KID, getAccountUrl(account, staging)); } protectedHeaderBuilder .add(NONCE, base64UrlEncode(getNonce(account, staging))) .add(URL, resourceUrl); return getEncodedJson(protectedHeaderBuilder.build()); }
/** * Get the key authorization string for this challenge. * * @param account the ACME account information to use (must not be {@code null}) * @return the key authorization string for this challenge * @throws AcmeException if the key authorization string cannot be determined */ public String getKeyAuthorization(AcmeAccount account) throws AcmeException { Assert.checkNotNullParam("account", account); JsonObject jwk = getJwk(account.getPublicKey(), account.getAlgHeader()); byte[] jwkWithoutWhitespace = CodePointIterator.ofString(jwk.toString()).skip(Character::isWhitespace).skipCrLf().asUtf8().drain(); try { MessageDigest messageDigest = MessageDigest.getInstance("SHA-256"); messageDigest.update(jwkWithoutWhitespace); byte[] jwkThumbprint = messageDigest.digest(); return token + "." + base64UrlEncode(jwkThumbprint); } catch (NoSuchAlgorithmException e) { throw acme.unableToDetermineKeyAuthorizationString(e); } }
/** * Get the key authorization string for this challenge. * * @param account the ACME account information to use (must not be {@code null}) * @return the key authorization string for this challenge * @throws AcmeException if the key authorization string cannot be determined */ public String getKeyAuthorization(AcmeAccount account) throws AcmeException { Assert.checkNotNullParam("account", account); JsonObject jwk = getJwk(account.getPublicKey(), account.getAlgHeader()); byte[] jwkWithoutWhitespace = CodePointIterator.ofString(jwk.toString()).skip(Character::isWhitespace).skipCrLf().asUtf8().drain(); try { MessageDigest messageDigest = MessageDigest.getInstance("SHA-256"); messageDigest.update(jwkWithoutWhitespace); byte[] jwkThumbprint = messageDigest.digest(); return token + "." + base64UrlEncode(jwkThumbprint); } catch (NoSuchAlgorithmException e) { throw acme.unableToDetermineKeyAuthorizationString(e); } }
/** * Get the key authorization string for this challenge. * * @param account the ACME account information to use (must not be {@code null}) * @return the key authorization string for this challenge * @throws AcmeException if the key authorization string cannot be determined */ public String getKeyAuthorization(AcmeAccount account) throws AcmeException { Assert.checkNotNullParam("account", account); JsonObject jwk = getJwk(account.getPublicKey(), account.getAlgHeader()); byte[] jwkWithoutWhitespace = CodePointIterator.ofString(jwk.toString()).skip(Character::isWhitespace).skipCrLf().asUtf8().drain(); try { MessageDigest messageDigest = MessageDigest.getInstance("SHA-256"); messageDigest.update(jwkWithoutWhitespace); byte[] jwkThumbprint = messageDigest.digest(); return token + "." + base64UrlEncode(jwkThumbprint); } catch (NoSuchAlgorithmException e) { throw acme.unableToDetermineKeyAuthorizationString(e); } }
/** * Change the key that is associated with the given ACME account. * * @param account the ACME account information to use (must not be {@code null}) * @param staging whether or not the staging server URL should be used * @param certificate the new certificate to associate with the given ACME account (must not be {@code null}) * @param privateKey the new private key to associate with the given ACME account (must not be {@code null}) * @throws AcmeException if an error occurs while attempting to change the key that is associated with the given ACME account */ public void changeAccountKey(AcmeAccount account, boolean staging, X509Certificate certificate, PrivateKey privateKey) throws AcmeException { Assert.checkNotNullParam("account", account); Assert.checkNotNullParam("certificate", certificate); Assert.checkNotNullParam("privateKey", privateKey); final String keyChangeUrl = getResourceUrl(account, AcmeResource.KEY_CHANGE, staging).toString(); final String signatureAlgorithm = getDefaultCompatibleSignatureAlgorithmName(privateKey); final String algHeader = getAlgHeaderFromSignatureAlgorithm(signatureAlgorithm); final String innerEncodedProtectedHeader = getEncodedProtectedHeader(algHeader, certificate.getPublicKey(), keyChangeUrl); JsonObjectBuilder innerPayloadBuilder = Json.createObjectBuilder() .add(ACCOUNT, getAccountUrl(account, staging)) .add(OLD_KEY, getJwk(account.getPublicKey(), account.getAlgHeader())); final String innerEncodedPayload = getEncodedJson(innerPayloadBuilder.build()); final String innerEncodedSignature = getEncodedSignature(privateKey, signatureAlgorithm, innerEncodedProtectedHeader, innerEncodedPayload); final String outerEncodedPayload = getEncodedJson(getJws(innerEncodedProtectedHeader, innerEncodedPayload, innerEncodedSignature)); sendPostRequestWithRetries(account, staging, keyChangeUrl, false, outerEncodedPayload, HttpURLConnection.HTTP_OK); account.changeCertificateAndPrivateKey(certificate, privateKey); // update account info }
/** * Change the key that is associated with the given ACME account. * * @param account the ACME account information to use (must not be {@code null}) * @param staging whether or not the staging server URL should be used * @param certificate the new certificate to associate with the given ACME account (must not be {@code null}) * @param privateKey the new private key to associate with the given ACME account (must not be {@code null}) * @throws AcmeException if an error occurs while attempting to change the key that is associated with the given ACME account */ public void changeAccountKey(AcmeAccount account, boolean staging, X509Certificate certificate, PrivateKey privateKey) throws AcmeException { Assert.checkNotNullParam("account", account); Assert.checkNotNullParam("certificate", certificate); Assert.checkNotNullParam("privateKey", privateKey); final String keyChangeUrl = getResourceUrl(account, AcmeResource.KEY_CHANGE, staging).toString(); final String signatureAlgorithm = getDefaultCompatibleSignatureAlgorithmName(privateKey); final String algHeader = getAlgHeaderFromSignatureAlgorithm(signatureAlgorithm); final String innerEncodedProtectedHeader = getEncodedProtectedHeader(algHeader, certificate.getPublicKey(), keyChangeUrl); JsonObjectBuilder innerPayloadBuilder = Json.createObjectBuilder() .add(ACCOUNT, getAccountUrl(account, staging)) .add(OLD_KEY, getJwk(account.getPublicKey(), account.getAlgHeader())); final String innerEncodedPayload = getEncodedJson(innerPayloadBuilder.build()); final String innerEncodedSignature = getEncodedSignature(privateKey, signatureAlgorithm, innerEncodedProtectedHeader, innerEncodedPayload); final String outerEncodedPayload = getEncodedJson(getJws(innerEncodedProtectedHeader, innerEncodedPayload, innerEncodedSignature)); sendPostRequestWithRetries(account, staging, keyChangeUrl, false, outerEncodedPayload, HttpURLConnection.HTTP_OK); account.changeCertificateAndPrivateKey(certificate, privateKey); // update account info }
/** * Change the key that is associated with the given ACME account. * * @param account the ACME account information to use (must not be {@code null}) * @param staging whether or not the staging server URL should be used * @param certificate the new certificate to associate with the given ACME account (must not be {@code null}) * @param privateKey the new private key to associate with the given ACME account (must not be {@code null}) * @throws AcmeException if an error occurs while attempting to change the key that is associated with the given ACME account */ public void changeAccountKey(AcmeAccount account, boolean staging, X509Certificate certificate, PrivateKey privateKey) throws AcmeException { Assert.checkNotNullParam("account", account); Assert.checkNotNullParam("certificate", certificate); Assert.checkNotNullParam("privateKey", privateKey); final String keyChangeUrl = getResourceUrl(account, AcmeResource.KEY_CHANGE, staging).toString(); final String signatureAlgorithm = getDefaultCompatibleSignatureAlgorithmName(privateKey); final String algHeader = getAlgHeaderFromSignatureAlgorithm(signatureAlgorithm); final String innerEncodedProtectedHeader = getEncodedProtectedHeader(algHeader, certificate.getPublicKey(), keyChangeUrl); JsonObjectBuilder innerPayloadBuilder = Json.createObjectBuilder() .add(ACCOUNT, getAccountUrl(account, staging)) .add(OLD_KEY, getJwk(account.getPublicKey(), account.getAlgHeader())); final String innerEncodedPayload = getEncodedJson(innerPayloadBuilder.build()); final String innerEncodedSignature = getEncodedSignature(privateKey, signatureAlgorithm, innerEncodedProtectedHeader, innerEncodedPayload); final String outerEncodedPayload = getEncodedJson(getJws(innerEncodedProtectedHeader, innerEncodedPayload, innerEncodedSignature)); sendPostRequestWithRetries(account, staging, keyChangeUrl, false, outerEncodedPayload, HttpURLConnection.HTTP_OK); account.changeCertificateAndPrivateKey(certificate, privateKey); // update account info }