Class: OpenSSL::PKey::EC::Group

Inherits:
Object
  • Object
show all
Defined in:
ext/openssl/ossl_pkey_ec.c

Defined Under Namespace

Classes: Error

Instance Method Summary collapse

Constructor Details

#OpenSSL::PKey::EC::Group.new(ec_group) ⇒ Object #OpenSSL::PKey::EC::Group.new(pem_or_der_encoded) ⇒ Object #OpenSSL::PKey::EC::Group.new(: GFp, bignum_p, bignum_a, bignum_b) ⇒ Object #OpenSSL::PKey::EC::Group.new(: GF2m, bignum_p, bignum_a, bignum_b) ⇒ Object

Creates a new EC::Group object.

If the first argument is :GFp or :GF2m, creates a new curve with given parameters.



629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
# File 'ext/openssl/ossl_pkey_ec.c', line 629

static VALUE ossl_ec_group_initialize(int argc, VALUE *argv, VALUE self)
{
    VALUE arg1, arg2, arg3, arg4;
    EC_GROUP *group;

    TypedData_Get_Struct(self, EC_GROUP, &ossl_ec_group_type, group);
    if (group)
        ossl_raise(rb_eRuntimeError, "EC_GROUP is already initialized");

    switch (rb_scan_args(argc, argv, "13", &arg1, &arg2, &arg3, &arg4)) {
      case 1:
        if (rb_obj_is_kind_of(arg1, cEC_GROUP)) {
            const EC_GROUP *arg1_group;

            GetECGroup(arg1, arg1_group);
            if ((group = EC_GROUP_dup(arg1_group)) == NULL)
                ossl_raise(eEC_GROUP, "EC_GROUP_dup");
        } else {
            BIO *in = ossl_obj2bio(&arg1);

            group = PEM_read_bio_ECPKParameters(in, NULL, NULL, NULL);
            if (!group) {
                OSSL_BIO_reset(in);
                group = d2i_ECPKParameters_bio(in, NULL);
            }

            BIO_free(in);

            if (!group) {
                const char *name = StringValueCStr(arg1);
                int nid = OBJ_sn2nid(name);

                ossl_clear_error(); /* ignore errors in d2i_ECPKParameters_bio() */
                if (nid == NID_undef)
                    ossl_raise(eEC_GROUP, "unknown curve name (%"PRIsVALUE")", arg1);
#if !defined(OPENSSL_IS_AWSLC)
                group = EC_GROUP_new_by_curve_name(nid);
#else /* EC_GROUPs are static and immutable by default in AWS-LC. */
                group = EC_GROUP_new_by_curve_name_mutable(nid);
#endif
                if (group == NULL)
                    ossl_raise(eEC_GROUP, "unable to create curve (%"PRIsVALUE")", arg1);

                EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
                EC_GROUP_set_point_conversion_form(group, POINT_CONVERSION_UNCOMPRESSED);
            }
        }

        break;
      case 4:
        if (SYMBOL_P(arg1)) {
            EC_GROUP *(*new_curve)(const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *) = NULL;
            const BIGNUM *p = GetBNPtr(arg2);
            const BIGNUM *a = GetBNPtr(arg3);
            const BIGNUM *b = GetBNPtr(arg4);

            if (arg1 == sym_GFp) {
                new_curve = EC_GROUP_new_curve_GFp;
            }
#if !defined(OPENSSL_NO_EC2M)
            else if (arg1 == sym_GF2m) {
                new_curve = EC_GROUP_new_curve_GF2m;
            }
#endif
            else {
                ossl_raise(rb_eArgError, "unknown symbol, must be :GFp or :GF2m");
            }

            if ((group = new_curve(p, a, b, ossl_bn_ctx)) == NULL)
                ossl_raise(eEC_GROUP, "EC_GROUP_new_by_GF*");
        } else {
            ossl_raise(rb_eArgError, "unknown argument, must be :GFp or :GF2m");
        }

        break;
      default:
        ossl_raise(rb_eArgError, "wrong number of arguments");
    }

    ASSUME(group);
    RTYPEDDATA_DATA(self) = group;

    return self;
}

Instance Method Details

#asn1_flagInteger

Returns the flags set on the group.

See also #asn1_flag=.

Returns:



916
917
918
919
920
921
922
923
924
925
# File 'ext/openssl/ossl_pkey_ec.c', line 916

static VALUE ossl_ec_group_get_asn1_flag(VALUE self)
{
    EC_GROUP *group = NULL;
    int flag;

    GetECGroup(self, group);
    flag = EC_GROUP_get_asn1_flag(group);

    return INT2NUM(flag);
}

#asn1_flag=(flags) ⇒ Object

Sets flags on the group. The flag value is used to determine how to encode the group: encode explicit parameters or named curve using an OID.

The flag value can be either of:

  • EC::NAMED_CURVE

  • EC::EXPLICIT_CURVE

See the OpenSSL documentation for EC_GROUP_set_asn1_flag().



941
942
943
944
945
946
947
948
949
# File 'ext/openssl/ossl_pkey_ec.c', line 941

static VALUE ossl_ec_group_set_asn1_flag(VALUE self, VALUE flag_v)
{
    EC_GROUP *group = NULL;

    GetECGroup(self, group);
    EC_GROUP_set_asn1_flag(group, NUM2INT(flag_v));

    return flag_v;
}

#get_cofactorObject

Returns the cofactor of the group.

See the OpenSSL documentation for EC_GROUP_get_cofactor()



834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
# File 'ext/openssl/ossl_pkey_ec.c', line 834

static VALUE ossl_ec_group_get_cofactor(VALUE self)
{
    VALUE bn_obj;
    BIGNUM *bn;
    EC_GROUP *group;

    GetECGroup(self, group);
    bn_obj = ossl_bn_new(BN_value_one());
    bn = GetBNPtr(bn_obj);

    if (EC_GROUP_get_cofactor(group, bn, ossl_bn_ctx) != 1)
        ossl_raise(eEC_GROUP, "EC_GROUP_get_cofactor");

    return bn_obj;
}

#curve_nameString?

Returns the curve name (short name) corresponding to this group, or nil if OpenSSL does not have an OID associated with the group.

See the OpenSSL documentation for EC_GROUP_get_curve_name()

Returns:

  • (String, nil)


859
860
861
862
863
864
865
866
867
868
869
# File 'ext/openssl/ossl_pkey_ec.c', line 859

static VALUE ossl_ec_group_get_curve_name(VALUE self)
{
    EC_GROUP *group;
    int nid;

    GetECGroup(self, group);
    nid = EC_GROUP_get_curve_name(group);
    if (nid == NID_undef)
        return Qnil;
    return rb_str_new_cstr(OBJ_nid2sn(nid));
}

#degreeInteger

See the OpenSSL documentation for EC_GROUP_get_degree()

Returns:



1073
1074
1075
1076
1077
1078
1079
1080
# File 'ext/openssl/ossl_pkey_ec.c', line 1073

static VALUE ossl_ec_group_get_degree(VALUE self)
{
    EC_GROUP *group = NULL;

    GetECGroup(self, group);

    return INT2NUM(EC_GROUP_get_degree(group));
}

#eql?(group2) ⇒ Boolean #==(group2) ⇒ Boolean Also known as: ==

Returns true if the two groups use the same curve and have the same parameters, false otherwise.

Returns:

  • (Boolean)


741
742
743
744
745
746
747
748
749
750
751
752
753
# File 'ext/openssl/ossl_pkey_ec.c', line 741

static VALUE ossl_ec_group_eql(VALUE a, VALUE b)
{
    EC_GROUP *group1 = NULL, *group2 = NULL;

    GetECGroup(a, group1);
    GetECGroup(b, group2);

    switch (EC_GROUP_cmp(group1, group2, ossl_bn_ctx)) {
      case 0: return Qtrue;
      case 1: return Qfalse;
      default: ossl_raise(eEC_GROUP, "EC_GROUP_cmp");
    }
}

#generatorObject

Returns the generator of the group.

See the OpenSSL documentation for EC_GROUP_get0_generator()



763
764
765
766
767
768
769
770
771
772
773
774
# File 'ext/openssl/ossl_pkey_ec.c', line 763

static VALUE ossl_ec_group_get_generator(VALUE self)
{
    EC_GROUP *group;
    const EC_POINT *generator;

    GetECGroup(self, group);
    generator = EC_GROUP_get0_generator(group);
    if (!generator)
        return Qnil;

    return ec_point_new(generator, group);
}

#initialize_copy(other) ⇒ Object

:nodoc:



715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
# File 'ext/openssl/ossl_pkey_ec.c', line 715

static VALUE
ossl_ec_group_initialize_copy(VALUE self, VALUE other)
{
    EC_GROUP *group, *group_new;

    TypedData_Get_Struct(self, EC_GROUP, &ossl_ec_group_type, group_new);
    if (group_new)
        ossl_raise(eEC_GROUP, "EC::Group already initialized");
    GetECGroup(other, group);

    group_new = EC_GROUP_dup(group);
    if (!group_new)
        ossl_raise(eEC_GROUP, "EC_GROUP_dup");
    RTYPEDDATA_DATA(self) = group_new;

    return self;
}

#get_orderObject

Returns the order of the group.

See the OpenSSL documentation for EC_GROUP_get_order()



810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
# File 'ext/openssl/ossl_pkey_ec.c', line 810

static VALUE ossl_ec_group_get_order(VALUE self)
{
    VALUE bn_obj;
    BIGNUM *bn;
    EC_GROUP *group;

    GetECGroup(self, group);
    bn_obj = ossl_bn_new(BN_value_one());
    bn = GetBNPtr(bn_obj);

    if (EC_GROUP_get_order(group, bn, ossl_bn_ctx) != 1)
        ossl_raise(eEC_GROUP, "EC_GROUP_get_order");

    return bn_obj;
}

#point_conversion_formSymbol

Returns the form how EC::Point data is encoded as ASN.1.

See also #point_conversion_form=.

Returns:

  • (Symbol)


959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
# File 'ext/openssl/ossl_pkey_ec.c', line 959

static VALUE ossl_ec_group_get_point_conversion_form(VALUE self)
{
    EC_GROUP *group;
    point_conversion_form_t form;

    GetECGroup(self, group);
    form = EC_GROUP_get_point_conversion_form(group);

    switch (form) {
      case POINT_CONVERSION_UNCOMPRESSED:
        return sym_uncompressed;
      case POINT_CONVERSION_COMPRESSED:
        return sym_compressed;
      case POINT_CONVERSION_HYBRID:
        return sym_hybrid;
      default:
        ossl_raise(eEC_GROUP, "unsupported point conversion form: %d, " \
                   "this module should be updated", form);
    }
}

#point_conversion_form=(form) ⇒ Object

Sets the form how EC::Point data is encoded as ASN.1 as defined in X9.62.

format can be one of these:

:compressed

Encoded as z||x, where z is an octet indicating which solution of the equation y is. z will be 0x02 or 0x03.

:uncompressed

Encoded as z||x||y, where z is an octet 0x04.

:hybrid

Encodes as z||x||y, where z is an octet indicating which solution of the equation y is. z will be 0x06 or 0x07.

See the OpenSSL documentation for EC_GROUP_set_point_conversion_form()



1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
# File 'ext/openssl/ossl_pkey_ec.c', line 1012

static VALUE
ossl_ec_group_set_point_conversion_form(VALUE self, VALUE form_v)
{
    EC_GROUP *group;
    point_conversion_form_t form;

    GetECGroup(self, group);
    form = parse_point_conversion_form_symbol(form_v);

    EC_GROUP_set_point_conversion_form(group, form);

    return form_v;
}

#seedString?

See the OpenSSL documentation for EC_GROUP_get0_seed()

Returns:

  • (String, nil)


1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
# File 'ext/openssl/ossl_pkey_ec.c', line 1032

static VALUE ossl_ec_group_get_seed(VALUE self)
{
    EC_GROUP *group = NULL;
    size_t seed_len;

    GetECGroup(self, group);
    seed_len = EC_GROUP_get_seed_len(group);

    if (seed_len == 0)
        return Qnil;

    return rb_str_new((const char *)EC_GROUP_get0_seed(group), seed_len);
}

#seed=(seed) ⇒ Object

See the OpenSSL documentation for EC_GROUP_set_seed()



1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
# File 'ext/openssl/ossl_pkey_ec.c', line 1052

static VALUE ossl_ec_group_set_seed(VALUE self, VALUE seed)
{
    EC_GROUP *group = NULL;

    GetECGroup(self, group);
    StringValue(seed);

    if (EC_GROUP_set_seed(group, (unsigned char *)RSTRING_PTR(seed), RSTRING_LEN(seed)) != (size_t)RSTRING_LEN(seed))
        ossl_raise(eEC_GROUP, "EC_GROUP_set_seed");

    return seed;
}

#set_generator(generator, order, cofactor) ⇒ self

Sets the curve parameters. generator must be an instance of EC::Point that is on the curve. order and cofactor are integers.

See the OpenSSL documentation for EC_GROUP_set_generator()

Returns:

  • (self)


785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
# File 'ext/openssl/ossl_pkey_ec.c', line 785

static VALUE ossl_ec_group_set_generator(VALUE self, VALUE generator, VALUE order, VALUE cofactor)
{
    EC_GROUP *group = NULL;
    const EC_POINT *point;
    const BIGNUM *o, *co;

    GetECGroup(self, group);
    GetECPoint(generator, point);
    o = GetBNPtr(order);
    co = GetBNPtr(cofactor);

    if (EC_GROUP_set_generator(group, point, o, co) != 1)
        ossl_raise(eEC_GROUP, "EC_GROUP_set_generator");

    return self;
}

#to_derString

See the OpenSSL documentation for i2d_ECPKParameters_bio()

Returns:

  • (String)


1133
1134
1135
1136
# File 'ext/openssl/ossl_pkey_ec.c', line 1133

static VALUE ossl_ec_group_to_der(VALUE self)
{
    return ossl_ec_group_to_string(self, EXPORT_DER);
}

#to_pemString

See the OpenSSL documentation for PEM_write_bio_ECPKParameters()

Returns:

  • (String)


1122
1123
1124
1125
# File 'ext/openssl/ossl_pkey_ec.c', line 1122

static VALUE ossl_ec_group_to_pem(VALUE self)
{
    return ossl_ec_group_to_string(self, EXPORT_PEM);
}

#to_textString

See the OpenSSL documentation for ECPKParameters_print()

Returns:

  • (String)


1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
# File 'ext/openssl/ossl_pkey_ec.c', line 1144

static VALUE ossl_ec_group_to_text(VALUE self)
{
    EC_GROUP *group;
    BIO *out;
    VALUE str;

    GetECGroup(self, group);
    if (!(out = BIO_new(BIO_s_mem()))) {
        ossl_raise(eEC_GROUP, "BIO_new(BIO_s_mem())");
    }
    if (!ECPKParameters_print(out, group, 0)) {
        BIO_free(out);
        ossl_raise(eEC_GROUP, NULL);
    }
    str = ossl_membio2str(out);

    return str;
}