@@ -491,4 +491,105 @@ def test_verify_same_subject_ca
491491 assert_equal false , ok # OpenSSL 1.1.1 behavior
492492 end
493493
494+ # Constant value assertions — portable across CRuby and JRuby.
495+ # Values match OpenSSL 1.1.1 (some were renumbered in 3.x).
496+ def test_v_err_constants
497+ x = OpenSSL ::X509
498+ assert_equal 0 , x ::V_OK
499+ assert_equal 1 , x ::V_ERR_UNSPECIFIED
500+ assert_equal 18 , x ::V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT
501+ assert_equal 19 , x ::V_ERR_SELF_SIGNED_CERT_IN_CHAIN
502+ assert_equal 20 , x ::V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY
503+ assert_equal 33 , x ::V_ERR_UNABLE_TO_GET_CRL_ISSUER
504+ assert_equal 34 , x ::V_ERR_UNHANDLED_CRITICAL_EXTENSION
505+ assert_equal 35 , x ::V_ERR_KEYUSAGE_NO_CRL_SIGN
506+ assert_equal 37 , x ::V_ERR_INVALID_NON_CA
507+ assert_equal 40 , x ::V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED
508+ assert_equal 43 , x ::V_ERR_NO_EXPLICIT_POLICY
509+ assert_equal 50 , x ::V_ERR_APPLICATION_VERIFICATION
510+ assert_equal 55 , x ::V_ERR_PATH_LOOP
511+ assert_equal 62 , x ::V_ERR_HOSTNAME_MISMATCH
512+ assert_equal 63 , x ::V_ERR_EMAIL_MISMATCH
513+ assert_equal 64 , x ::V_ERR_IP_ADDRESS_MISMATCH
514+ assert_equal 69 , x ::V_ERR_INVALID_CALL
515+ assert_equal 70 , x ::V_ERR_STORE_LOOKUP
516+ end
517+
518+ def test_v_flag_constants
519+ x = OpenSSL ::X509
520+ assert_equal 0x4 , x ::V_FLAG_CRL_CHECK
521+ assert_equal 0x8 , x ::V_FLAG_CRL_CHECK_ALL
522+ assert_equal 0x2 , x ::V_FLAG_USE_CHECK_TIME
523+ assert_equal 0x10 , x ::V_FLAG_IGNORE_CRITICAL
524+ assert_equal 0x20 , x ::V_FLAG_X509_STRICT
525+ assert_equal 0x40 , x ::V_FLAG_ALLOW_PROXY_CERTS
526+ assert_equal 0x80 , x ::V_FLAG_POLICY_CHECK
527+ assert_equal 0x100 , x ::V_FLAG_EXPLICIT_POLICY
528+ assert_equal 0x200 , x ::V_FLAG_INHIBIT_ANY
529+ assert_equal 0x400 , x ::V_FLAG_INHIBIT_MAP
530+ assert_equal 0x800 , x ::V_FLAG_NOTIFY_POLICY
531+ assert_equal 0x4000 , x ::V_FLAG_CHECK_SS_SIGNATURE
532+ assert_equal 0x8000 , x ::V_FLAG_TRUSTED_FIRST
533+ assert_equal 0x80000 , x ::V_FLAG_PARTIAL_CHAIN
534+ assert_equal 0x100000 , x ::V_FLAG_NO_ALT_CHAINS
535+ assert_equal 0x200000 , x ::V_FLAG_NO_CHECK_TIME
536+ end
537+
538+ def test_v_flag_no_check_time
539+ now = Time . now
540+ ca_exts = [ [ "basicConstraints" , "CA:TRUE" , true ] , [ "keyUsage" , "cRLSign,keyCertSign" , true ] ]
541+ ee_exts = [ [ "keyUsage" , "keyEncipherment,digitalSignature" , true ] ]
542+ ca_key = OpenSSL ::PKey ::RSA . new ( 2048 )
543+ ca_cert = issue_cert ( OpenSSL ::X509 ::Name . parse ( "/CN=CA" ) , ca_key , 1 , ca_exts , nil , nil ,
544+ not_before : now , not_after : now + 3600 )
545+ ee_key = OpenSSL ::PKey ::RSA . new ( 2048 )
546+ # expired cert
547+ expired = issue_cert ( OpenSSL ::X509 ::Name . parse ( "/CN=Expired" ) , ee_key , 2 , ee_exts , ca_cert , ca_key ,
548+ not_before : now - 7200 , not_after : now - 3600 )
549+
550+ # Without NO_CHECK_TIME: expired cert fails
551+ store = OpenSSL ::X509 ::Store . new
552+ store . add_cert ( ca_cert )
553+ assert_equal false , store . verify ( expired )
554+ assert_equal OpenSSL ::X509 ::V_ERR_CERT_HAS_EXPIRED , store . error
555+
556+ # With NO_CHECK_TIME: expired cert passes
557+ store2 = OpenSSL ::X509 ::Store . new
558+ store2 . add_cert ( ca_cert )
559+ store2 . flags = OpenSSL ::X509 ::V_FLAG_NO_CHECK_TIME
560+ assert_equal true , store2 . verify ( expired )
561+ assert_equal OpenSSL ::X509 ::V_OK , store2 . error
562+ end
563+
564+ def test_v_flag_partial_chain
565+ # TODO: V_FLAG_PARTIAL_CHAIN is functional in StoreContext.check_trust
566+ # but chain building doesn't fully support it yet on JRuby
567+ skip 'PARTIAL_CHAIN chain building not fully working' if defined? ( JRUBY_VERSION )
568+
569+ now = Time . now
570+ ca_exts = [ [ "basicConstraints" , "CA:TRUE" , true ] , [ "keyUsage" , "cRLSign,keyCertSign" , true ] ]
571+ ee_exts = [ [ "keyUsage" , "keyEncipherment,digitalSignature" , true ] ]
572+ root_key = OpenSSL ::PKey ::RSA . new ( 2048 )
573+ root_cert = issue_cert ( OpenSSL ::X509 ::Name . parse ( "/CN=Root" ) , root_key , 1 , ca_exts , nil , nil ,
574+ not_before : now , not_after : now + 3600 )
575+ inter_key = OpenSSL ::PKey ::RSA . new ( 2048 )
576+ inter_cert = issue_cert ( OpenSSL ::X509 ::Name . parse ( "/CN=Intermediate" ) , inter_key , 2 , ca_exts ,
577+ root_cert , root_key , not_before : now , not_after : now + 3600 )
578+ ee_key = OpenSSL ::PKey ::RSA . new ( 2048 )
579+ ee_cert = issue_cert ( OpenSSL ::X509 ::Name . parse ( "/CN=Leaf" ) , ee_key , 3 , ee_exts ,
580+ inter_cert , inter_key , not_before : now , not_after : now + 1800 )
581+
582+ # Without PARTIAL_CHAIN: only intermediate in store, leaf verification fails
583+ store = OpenSSL ::X509 ::Store . new
584+ store . add_cert ( inter_cert )
585+ assert_equal false , store . verify ( ee_cert )
586+
587+ # With PARTIAL_CHAIN: intermediate is accepted as trust anchor
588+ store2 = OpenSSL ::X509 ::Store . new
589+ store2 . add_cert ( inter_cert )
590+ store2 . flags = OpenSSL ::X509 ::V_FLAG_PARTIAL_CHAIN
591+ assert_equal true , store2 . verify ( ee_cert )
592+ assert_equal OpenSSL ::X509 ::V_OK , store2 . error
593+ end
594+
494595end
0 commit comments