6464import org .jruby .ext .openssl .x509store .PEMInputOutput ;
6565import static org .jruby .ext .openssl .OpenSSL .*;
6666import org .jruby .ext .openssl .impl .CipherSpec ;
67+ import org .jruby .util .ByteList ;
6768
6869/**
6970 * @author <a href="mailto:ola.bini@ki.se">Ola Bini</a>
@@ -187,6 +188,8 @@ public IRubyObject initialize(ThreadContext context) {
187188
188189 public String getAlgorithm () { return "NONE" ; }
189190
191+ public boolean isPrivateKey () { return getPrivateKey () != null ; }
192+
190193 public abstract RubyString to_der () ;
191194
192195 public abstract RubyString to_pem (final IRubyObject [] args ) ;
@@ -198,54 +201,66 @@ public RubyString export(final IRubyObject[] args) {
198201
199202 @ JRubyMethod (name = "sign" )
200203 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." );
203207 }
204208 String digAlg = ((Digest ) digest ).getShortAlgorithm ();
205209 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 );
212212 }
213- catch (GeneralSecurityException gse ) {
214- throw newPKeyError (getRuntime (), gse .getMessage ());
213+ catch (GeneralSecurityException ex ) {
214+ throw newPKeyError (runtime , ex .getMessage ());
215215 }
216216 }
217217
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+
218226 @ 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 ();
220229 if ( ! (digest instanceof Digest ) ) {
221- throw newPKeyError (getRuntime () , "invalid digest" );
230+ throw newPKeyError (runtime , "invalid digest" );
222231 }
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 ();
231234 String algorithm = ((Digest ) digest ).getShortAlgorithm () + "WITH" + getAlgorithm ();
232- boolean valid ;
233235 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 ) );
238237 }
239238 catch (NoSuchAlgorithmException e ) {
240- throw newPKeyError (getRuntime () , "unsupported algorithm: " + algorithm );
239+ throw newPKeyError (runtime , "unsupported algorithm: " + algorithm );
241240 }
242241 catch (SignatureException e ) {
243- throw newPKeyError (getRuntime () , "invalid signature" );
242+ throw newPKeyError (runtime , "invalid signature" );
244243 }
245244 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 ();
247252 }
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 ());
249264 }
250265
251266 // shared Helpers for PKeyRSA / PKEyDSA :
0 commit comments