Skip to content

Commit 4b2968b

Browse files
committed
[refactor] review deprecated APIs on certificate sign
1 parent da68ef3 commit 4b2968b

File tree

2 files changed

+47
-42
lines changed

2 files changed

+47
-42
lines changed

src/main/java/org/jruby/ext/openssl/X509Cert.java

Lines changed: 47 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
import java.io.StringWriter;
3333
import java.math.BigInteger;
3434

35-
import java.security.GeneralSecurityException;
3635
import java.security.InvalidKeyException;
3736
import java.security.NoSuchAlgorithmException;
3837
import java.security.NoSuchProviderException;
@@ -60,6 +59,12 @@
6059
import org.bouncycastle.asn1.x509.GeneralName;
6160
import org.bouncycastle.asn1.x509.GeneralNames;
6261

62+
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
63+
import org.bouncycastle.cert.X509CertificateHolder;
64+
import org.bouncycastle.cert.X509v3CertificateBuilder;
65+
import org.bouncycastle.operator.ContentSigner;
66+
import org.bouncycastle.operator.OperatorCreationException;
67+
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
6368
import org.joda.time.DateTime;
6469
import org.jruby.Ruby;
6570
import org.jruby.RubyArray;
@@ -593,60 +598,70 @@ else if (digest instanceof RubyString) {
593598
throw newCertificateError(runtime, "signature_algorithm not supported");
594599
}
595600

596-
org.bouncycastle.x509.X509V3CertificateGenerator builder = getCertificateBuilder();
597-
601+
final X509v3CertificateBuilder builder = newCertificateBuilder();
598602
for ( X509Extension ext : uniqueExtensions() ) {
599603
try {
600604
final byte[] bytes = ext.getRealValueEncoded();
601-
builder.addExtension(ext.getRealObjectID().getId(), ext.isRealCritical(), bytes);
605+
builder.addExtension(ext.getRealObjectID(), ext.isRealCritical(), bytes);
602606
}
603-
catch (IOException ioe) {
604-
throw runtime.newIOErrorFromException(ioe);
607+
catch (IOException e) {
608+
throw newCertificateError(runtime, "invalid extension (" + e.getMessage() + ")", e);
605609
}
606610
}
607611

608-
builder.setSignatureAlgorithm(digAlg + "WITH" + keyAlg); // "SHA1WITHRSA"
609-
612+
final X509CertificateHolder certHolder;
610613
try {
611-
cert = builder.generate( ((PKey) key).getPrivateKey() );
612-
}
613-
catch (GeneralSecurityException e) {
614-
throw newCertificateError(runtime, e);
615-
}
616-
catch (IllegalStateException e) {
614+
ContentSigner signer =
615+
new JcaContentSignerBuilder(digAlg + "WITH" + keyAlg).
616+
build(((PKey) key).getPrivateKey());
617+
certHolder = builder.build(signer);
618+
} catch (OperatorCreationException e) {
619+
Exception cause = (Exception) e.getCause(); // GeneralSecurityException
620+
if (cause == null) cause = e;
621+
throw newCertificateError(runtime, "cannot create signer: " + cause.getMessage(), cause);
622+
} catch (IllegalStateException e) {
617623
// e.g. "not all mandatory fields set in V3 TBScertificate generator"
618624
throw newCertificateError(runtime, "could not generate certificate", e);
625+
} catch (RuntimeException e) {
626+
throw newCertificateError(runtime, e);
619627
}
620628

621-
if (cert == null) throw newCertificateError(runtime, (String) null);
629+
try {
630+
this.cert = (X509Certificate)
631+
SecurityHelper.getCertificateFactory("X.509").
632+
generateCertificate(new ByteArrayInputStream(certHolder.getEncoded()));
633+
} catch (IOException|CertificateException e) {
634+
throw newCertificateError(runtime, "could not re-generate certificate", e);
635+
}
622636

623-
String name = ASN1Registry.o2a(cert.getSigAlgOID());
637+
String name = ASN1Registry.o2a(certHolder.getSignatureAlgorithm().getAlgorithm());
624638
if ( name == null ) name = cert.getSigAlgOID();
625639
this.sig_alg = runtime.newString(name);
626640
this.changed = false;
627641
return this;
628642
}
629643

630-
private org.bouncycastle.x509.X509V3CertificateGenerator getCertificateBuilder() {
631-
org.bouncycastle.x509.X509V3CertificateGenerator generator =
632-
new org.bouncycastle.x509.X509V3CertificateGenerator();
633-
if ( serial.equals(BigInteger.ZERO) ) { // NOTE: diversion from MRI (OpenSSL allows not setting serial)
634-
throw newCertificateError(getRuntime(), "Certificate#serial needs to be set (to > 0)");
635-
}
636-
generator.setSerialNumber( serial.abs() );
637-
638-
if ( subject != null ) generator.setSubjectDN( ((X509Name) subject).getRealName() );
639-
if ( issuer != null ) generator.setIssuerDN( ((X509Name) issuer).getRealName() );
644+
private X509v3CertificateBuilder newCertificateBuilder() {
645+
//if ( serial.equals(BigInteger.ZERO) ) { // NOTE: diversion from MRI (OpenSSL allows not setting serial)
646+
// throw newCertificateError(getRuntime(), "Certificate#serial needs to be set (to > 0)");
647+
//}
640648

641-
generator.setNotBefore( not_before.getJavaDate() );
642-
generator.setNotAfter( not_after.getJavaDate() );
643-
generator.setPublicKey( getPublicKey() );
649+
SubjectPublicKeyInfo publicKeyInfo;
650+
try {
651+
publicKeyInfo = SubjectPublicKeyInfo.getInstance(public_key.getPublicKey().getEncoded());
652+
} catch (Exception e) {
653+
throw newCertificateError(getRuntime(), "invalid public key data", e);
654+
}
644655

645-
return generator;
656+
return new X509v3CertificateBuilder(
657+
issuer == null ? null : ((X509Name) issuer).getX500Name(),
658+
serial.abs(),
659+
not_before.getJavaDate(), not_after.getJavaDate(),
660+
subject == null ? null : ((X509Name) subject).getX500Name(),
661+
publicKeyInfo
662+
);
646663
}
647664

648-
//private transient org.bouncycastle.x509.X509V3CertificateGenerator generator;
649-
650665
@JRubyMethod
651666
public RubyBoolean verify(final IRubyObject key) {
652667
final Ruby runtime = getRuntime();

src/main/java/org/jruby/ext/openssl/X509Name.java

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -526,16 +526,6 @@ private static String name(final Ruby runtime, final ASN1ObjectIdentifier oid) {
526526
return ASN1.oid2name(runtime, oid, true);
527527
}
528528

529-
@Deprecated
530-
@SuppressWarnings("unchecked")
531-
org.bouncycastle.asn1.x509.X509Name getRealName() {
532-
final java.util.Vector strValues = new java.util.Vector();
533-
for ( ASN1Encodable value : values ) strValues.add( value.toString() );
534-
return new org.bouncycastle.asn1.x509.X509Name(
535-
new java.util.Vector<Object>(oids), strValues
536-
);
537-
}
538-
539529
final X500Name getX500Name() {
540530
if ( name != null ) return name;
541531

0 commit comments

Comments
 (0)