64
64
import org .jruby .ext .openssl .x509store .PEMInputOutput ;
65
65
import static org .jruby .ext .openssl .OpenSSL .*;
66
66
import org .jruby .ext .openssl .impl .CipherSpec ;
67
+ import org .jruby .util .ByteList ;
67
68
68
69
/**
69
70
* @author <a href="mailto:[email protected] ">Ola Bini</a>
@@ -187,6 +188,8 @@ public IRubyObject initialize(ThreadContext context) {
187
188
188
189
public String getAlgorithm () { return "NONE" ; }
189
190
191
+ public boolean isPrivateKey () { return getPrivateKey () != null ; }
192
+
190
193
public abstract RubyString to_der () ;
191
194
192
195
public abstract RubyString to_pem (final IRubyObject [] args ) ;
@@ -198,54 +201,66 @@ public RubyString export(final IRubyObject[] args) {
198
201
199
202
@ JRubyMethod (name = "sign" )
200
203
public IRubyObject sign (IRubyObject digest , IRubyObject data ) {
201
- if (!this .callMethod (getRuntime ().getCurrentContext (), "private?" ).isTrue ()) {
202
- throw getRuntime ().newArgumentError ("Private key is needed." );
204
+ final Ruby runtime = getRuntime ();
205
+ if ( ! isPrivateKey () ) {
206
+ throw runtime .newArgumentError ("Private key is needed." );
203
207
}
204
208
String digAlg = ((Digest ) digest ).getShortAlgorithm ();
205
209
try {
206
- Signature signature = SecurityHelper .getSignature (digAlg + "WITH" + getAlgorithm ());
207
- signature .initSign (getPrivateKey ());
208
- byte [] inp = data .convertToString ().getBytes ();
209
- signature .update (inp );
210
- byte [] sigge = signature .sign ();
211
- return RubyString .newString (getRuntime (), sigge );
210
+ ByteList sign = sign (digAlg + "WITH" + getAlgorithm (), getPrivateKey (), data .convertToString ().getByteList ());
211
+ return RubyString .newString (runtime , sign );
212
212
}
213
- catch (GeneralSecurityException gse ) {
214
- throw newPKeyError (getRuntime (), gse .getMessage ());
213
+ catch (GeneralSecurityException ex ) {
214
+ throw newPKeyError (runtime , ex .getMessage ());
215
215
}
216
216
}
217
217
218
+ static ByteList sign (final String signAlg , final PrivateKey privateKey , final ByteList data )
219
+ throws NoSuchAlgorithmException , InvalidKeyException , SignatureException {
220
+ Signature signature = SecurityHelper .getSignature (signAlg );
221
+ signature .initSign ( privateKey );
222
+ signature .update ( data .getUnsafeBytes (), data .getBegin (), data .getRealSize () );
223
+ return new ByteList (signature .sign (), false );
224
+ }
225
+
218
226
@ JRubyMethod (name = "verify" )
219
- public IRubyObject verify (IRubyObject digest , IRubyObject sig , IRubyObject data ) {
227
+ public IRubyObject verify (IRubyObject digest , IRubyObject sign , IRubyObject data ) {
228
+ final Ruby runtime = getRuntime ();
220
229
if ( ! (digest instanceof Digest ) ) {
221
- throw newPKeyError (getRuntime () , "invalid digest" );
230
+ throw newPKeyError (runtime , "invalid digest" );
222
231
}
223
- if ( ! (sig instanceof RubyString ) ) {
224
- throw newPKeyError (getRuntime (), "invalid signature" );
225
- }
226
- if ( ! (data instanceof RubyString ) ) {
227
- throw newPKeyError (getRuntime (), "invalid data" );
228
- }
229
- byte [] sigBytes = ((RubyString ) sig ).getBytes ();
230
- byte [] dataBytes = ((RubyString ) data ).getBytes ();
232
+ ByteList sigBytes = convertToString (runtime , sign , "OpenSSL::PKey::PKeyError" , "invalid signature" ).getByteList ();
233
+ ByteList dataBytes = convertToString (runtime , data , "OpenSSL::PKey::PKeyError" , "invalid data" ).getByteList ();
231
234
String algorithm = ((Digest ) digest ).getShortAlgorithm () + "WITH" + getAlgorithm ();
232
- boolean valid ;
233
235
try {
234
- Signature signature = SecurityHelper .getSignature (algorithm );
235
- signature .initVerify (getPublicKey ());
236
- signature .update (dataBytes );
237
- valid = signature .verify (sigBytes );
236
+ return runtime .newBoolean ( verify (algorithm , getPublicKey (), dataBytes , sigBytes ) );
238
237
}
239
238
catch (NoSuchAlgorithmException e ) {
240
- throw newPKeyError (getRuntime () , "unsupported algorithm: " + algorithm );
239
+ throw newPKeyError (runtime , "unsupported algorithm: " + algorithm );
241
240
}
242
241
catch (SignatureException e ) {
243
- throw newPKeyError (getRuntime () , "invalid signature" );
242
+ throw newPKeyError (runtime , "invalid signature" );
244
243
}
245
244
catch (InvalidKeyException e ) {
246
- throw newPKeyError (getRuntime (), "invalid key" );
245
+ throw newPKeyError (runtime , "invalid key" );
246
+ }
247
+ }
248
+
249
+ static RubyString convertToString (final Ruby runtime , final IRubyObject str , final String errorType , final CharSequence errorMsg ) {
250
+ try {
251
+ return str .convertToString ();
247
252
}
248
- return getRuntime ().newBoolean (valid );
253
+ catch (RaiseException ex ) { // to_str conversion failed
254
+ throw Utils .newError (runtime , (RubyClass ) runtime .getClassFromPath (errorType ), errorMsg == null ? null : errorMsg .toString ());
255
+ }
256
+ }
257
+
258
+ static boolean verify (final String signAlg , final PublicKey publicKey , final ByteList data , final ByteList sign )
259
+ throws NoSuchAlgorithmException , InvalidKeyException , SignatureException {
260
+ Signature signature = SecurityHelper .getSignature (signAlg );
261
+ signature .initVerify (publicKey );
262
+ signature .update (data .getUnsafeBytes (), data .getBegin (), data .getRealSize ());
263
+ return signature .verify (sign .getUnsafeBytes (), sign .getBegin (), sign .getRealSize ());
249
264
}
250
265
251
266
// shared Helpers for PKeyRSA / PKEyDSA :
0 commit comments