Skip to content

Commit 6db2eb5

Browse files
committed
internally refactored Netscape::SPKI + it's impl NetscapeCertRequest
- cleanup up exception handling to be more predictable (les wrapping) - avoided BC deprecations + better support along various BC versions - added some stack trace debugging into a few suspicious places
1 parent 9c7828f commit 6db2eb5

File tree

2 files changed

+175
-190
lines changed

2 files changed

+175
-190
lines changed

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

Lines changed: 46 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
import java.io.IOException;
3131
import java.security.GeneralSecurityException;
32+
import java.security.NoSuchAlgorithmException;
3233
import java.security.PublicKey;
3334

3435
import org.bouncycastle.asn1.ASN1EncodableVector;
@@ -39,7 +40,6 @@
3940
import org.bouncycastle.asn1.ASN1Sequence;
4041
import org.bouncycastle.asn1.DLSequence;
4142
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
42-
//import org.bouncycastle.jce.netscape.NetscapeCertRequest;
4343

4444
import org.jruby.Ruby;
4545
import org.jruby.RubyClass;
@@ -52,14 +52,17 @@
5252
import org.jruby.runtime.ObjectAllocator;
5353
import org.jruby.runtime.Visibility;
5454
import org.jruby.runtime.builtin.IRubyObject;
55+
import org.jruby.runtime.ThreadContext;
5556
import org.jruby.runtime.Visibility;
57+
import org.jruby.util.ByteList;
5658

5759
// org.bouncycastle.jce.netscape.NetscapeCertRequest emulator:
5860
import org.jruby.ext.openssl.impl.NetscapeCertRequest;
5961

6062
import static org.jruby.ext.openssl.PKeyDSA._DSA;
6163
import static org.jruby.ext.openssl.PKeyRSA._RSA;
62-
import org.jruby.runtime.ThreadContext;
64+
import static org.jruby.ext.openssl.OpenSSLReal.debugStackTrace;
65+
import static org.jruby.ext.openssl.OpenSSLReal.warn;
6366

6467
/**
6568
* @author <a href="mailto:[email protected]">Ola Bini</a>
@@ -99,17 +102,17 @@ public NetscapeSPKI(Ruby runtime, RubyClass type) {
99102
public IRubyObject _initialize(final ThreadContext context, final IRubyObject[] args) {
100103
final Ruby runtime = context.runtime;
101104
if ( args.length > 0 ) {
102-
byte[] b = args[0].convertToString().getBytes();
103-
b = tryBase64Decode(b);
105+
byte[] request = args[0].convertToString().getBytes();
106+
request = tryBase64Decode(request);
104107

105108
final NetscapeCertRequest cert;
106109
try {
107-
this.cert = cert = new NetscapeCertRequest(b);
110+
this.cert = cert = new NetscapeCertRequest(request);
108111
challenge = runtime.newString( cert.getChallenge() );
109112
}
110-
catch (IOException ioe) {
111-
throw newSPKIError(runtime, ioe.getMessage());
112-
}
113+
catch (GeneralSecurityException e) { throw newSPKIError(e); }
114+
catch (IllegalArgumentException e) { throw newSPKIError(e); }
115+
113116
final PublicKey publicKey = cert.getPublicKey();
114117
final String algorithm = publicKey.getAlgorithm();
115118
final RubyString pub_key = RubyString.newString(runtime, publicKey.getEncoded());
@@ -128,34 +131,36 @@ else if ( "DSA".equalsIgnoreCase(algorithm) ) {
128131
}
129132

130133
// just try to decode for the time when the given bytes are base64 encoded.
131-
private byte[] tryBase64Decode(byte[] b) {
134+
private static byte[] tryBase64Decode(byte[] b) {
132135
try {
133136
b = Base64.decode(b, 0, b.length, Base64.NO_OPTIONS);
134-
} catch (Exception ignored) { }
137+
}
138+
catch (IOException ignored) { }
139+
catch (IllegalArgumentException ignored) { }
135140
return b;
136141
}
137142

138143
@JRubyMethod
139144
public IRubyObject to_der() {
140145
try {
141-
return RubyString.newString(getRuntime(), internalToDer());
142-
} catch (IOException ioe) {
143-
throw newSPKIError(getRuntime(), ioe.getMessage());
146+
final byte[] derBytes = toDER();
147+
return getRuntime().newString(new ByteList(derBytes, false));
144148
}
149+
catch (IOException ioe) { throw newSPKIError(ioe); }
145150
}
146151

147-
@JRubyMethod(name={"to_pem","to_s"})
152+
@JRubyMethod(name = { "to_pem", "to_s" })
148153
public IRubyObject to_pem() {
149154
try {
150-
byte[] source = internalToDer();
151-
// no Base64.DO_BREAK_LINES option needed for NSPKI.
152-
return getRuntime().newString(Base64.encodeBytes(source, 0, source.length, Base64.NO_OPTIONS));
153-
} catch (IOException ioe) {
154-
throw newSPKIError(getRuntime(), ioe.getMessage());
155+
byte[] source = toDER();
156+
// no Base64.DO_BREAK_LINES option needed for NSPKI :
157+
source = Base64.encodeBytesToBytes(source, 0, source.length, Base64.NO_OPTIONS);
158+
return getRuntime().newString(new ByteList(source, false));
155159
}
160+
catch (IOException ioe) { throw newSPKIError(ioe); }
156161
}
157162

158-
private byte[] internalToDer() throws IOException {
163+
private byte[] toDER() throws IOException {
159164
ASN1Sequence b = (ASN1Sequence) ((NetscapeCertRequest) cert).toASN1Primitive();
160165
ASN1ObjectIdentifier encType = (ASN1ObjectIdentifier)((ASN1Sequence)((ASN1Sequence)((ASN1Sequence)b.getObjectAt(0)).getObjectAt(0)).getObjectAt(0)).getObjectAt(0);
161166
ASN1ObjectIdentifier sigAlg = ((AlgorithmIdentifier)b.getObjectAt(1)).getAlgorithm();
@@ -170,22 +175,22 @@ private byte[] internalToDer() throws IOException {
170175
ASN1EncodableVector v3 = new ASN1EncodableVector();
171176
ASN1EncodableVector v4 = new ASN1EncodableVector();
172177
v4.add(encType);
173-
v4.add(new DERNull());
178+
v4.add(DERNull.INSTANCE);
174179
v3.add(new DLSequence(v4));
175180
v3.add(publicKey);
176181
v2.add(new DLSequence(v3));
177182
v2.add(encodedChallenge);
178183
v1.add(new DLSequence(v2));
179184
v1_2.add(sigAlg);
180-
v1_2.add(new DERNull());
185+
v1_2.add(DERNull.INSTANCE);
181186
v1.add(new DLSequence(v1_2));
182187
v1.add(sig);
183188
return new DLSequence(v1).getEncoded();
184189
}
185190

186191
@JRubyMethod
187192
public IRubyObject to_text() {
188-
System.err.println("WARNING: calling unimplemented method: to_text");
193+
warn(getRuntime().getCurrentContext(), "WARNING: unimplemented method called: Netscape::SPKI#to_text");
189194
return getRuntime().getNil();
190195
}
191196

@@ -206,28 +211,36 @@ public IRubyObject sign(final IRubyObject key, final IRubyObject digest) {
206211
final String symKey = keyAlg.toLowerCase() + '-' + digAlg.toLowerCase();
207212
try {
208213
final ASN1ObjectIdentifier alg = ASN1.getOIDLookup(getRuntime()).get( symKey );
209-
final PublicKey publicKey = ((PKey) public_key).getPublicKey();
214+
final PublicKey publicKey = ( (PKey) this.public_key ).getPublicKey();
210215
final String challengeStr = challenge.toString();
211216
final NetscapeCertRequest cert;
212217
this.cert = cert = new NetscapeCertRequest(challengeStr, new AlgorithmIdentifier(alg), publicKey);
213218
cert.sign( ((PKey) key).getPrivateKey() );
214219
}
215-
catch (GeneralSecurityException gse) {
216-
throw newSPKIError(getRuntime(), gse.getMessage());
220+
catch (NoSuchAlgorithmException e) {
221+
debugStackTrace(getRuntime(), e);
222+
throw newSPKIError(e);
223+
}
224+
catch (GeneralSecurityException e) {
225+
throw newSPKIError(e);
217226
}
218227
return this;
219228
}
220229

221230
@JRubyMethod
222231
public IRubyObject verify(final IRubyObject pkey) {
223232
final NetscapeCertRequest cert = (NetscapeCertRequest) this.cert;
224-
cert.setPublicKey(((PKey) pkey).getPublicKey());
233+
cert.setPublicKey( ((PKey) pkey).getPublicKey() );
225234
try {
226235
boolean result = cert.verify(challenge.toString());
227236
return getRuntime().newBoolean(result);
228237
}
229-
catch (GeneralSecurityException gse) {
230-
throw newSPKIError(getRuntime(), gse.getMessage());
238+
catch (NoSuchAlgorithmException e) {
239+
debugStackTrace(getRuntime(), e);
240+
throw newSPKIError(e);
241+
}
242+
catch (GeneralSecurityException e) {
243+
throw newSPKIError(e);
231244
}
232245
}
233246

@@ -241,6 +254,10 @@ public IRubyObject set_challenge(final IRubyObject challenge) {
241254
return this.challenge = challenge;
242255
}
243256

257+
private RaiseException newSPKIError(final Exception e) {
258+
return newSPKIError(getRuntime(), e.getMessage());
259+
}
260+
244261
private static RaiseException newSPKIError(Ruby runtime, String message) {
245262
return Utils.newError(runtime, _Netscape(runtime).getClass("SPKIError"), message);
246263
}

0 commit comments

Comments
 (0)