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.



627
628
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
# File 'ext/openssl/ossl_pkey_ec.c', line 627

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);

                group = EC_GROUP_new_by_curve_name(nid);
                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)) {
            ID id = SYM2ID(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 (id == s_GFp) {
                new_curve = EC_GROUP_new_curve_GFp;
#if !defined(OPENSSL_NO_EC2M)
            } else if (id == s_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:



913
914
915
916
917
918
919
920
921
922
# File 'ext/openssl/ossl_pkey_ec.c', line 913

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().



938
939
940
941
942
943
944
945
946
# File 'ext/openssl/ossl_pkey_ec.c', line 938

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()



828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
# File 'ext/openssl/ossl_pkey_ec.c', line 828

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

    GetECGroup(self, group);

    bn_obj = ossl_bn_new(NULL);
    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 (sn).

See the OpenSSL documentation for EC_GROUP_get_curve_name()

Returns:

  • (String)


853
854
855
856
857
858
859
860
861
862
863
864
865
866
# File 'ext/openssl/ossl_pkey_ec.c', line 853

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

    GetECGroup(self, group);
    if (group == NULL)
        return Qnil;

    nid = EC_GROUP_get_curve_name(group);

/* BUG: an nid or asn1 object should be returned, maybe. */
    return rb_str_new2(OBJ_nid2sn(nid));
}

#degreeInteger

See the OpenSSL documentation for EC_GROUP_get_degree()

Returns:



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

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)


734
735
736
737
738
739
740
741
742
743
744
745
746
# File 'ext/openssl/ossl_pkey_ec.c', line 734

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()



756
757
758
759
760
761
762
763
764
765
766
767
# File 'ext/openssl/ossl_pkey_ec.c', line 756

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



708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
# File 'ext/openssl/ossl_pkey_ec.c', line 708

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()



803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
# File 'ext/openssl/ossl_pkey_ec.c', line 803

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

    GetECGroup(self, group);

    bn_obj = ossl_bn_new(NULL);
    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)


956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
# File 'ext/openssl/ossl_pkey_ec.c', line 956

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

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

    switch (form) {
    case POINT_CONVERSION_UNCOMPRESSED:	ret = ID_uncompressed; break;
    case POINT_CONVERSION_COMPRESSED:	ret = ID_compressed; break;
    case POINT_CONVERSION_HYBRID:	ret = ID_hybrid; break;
    default:	ossl_raise(eEC_GROUP, "unsupported point conversion form: %d, this module should be updated", form);
    }

   return ID2SYM(ret);
}

#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()



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

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)


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

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()



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

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)


778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
# File 'ext/openssl/ossl_pkey_ec.c', line 778

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)


1131
1132
1133
1134
# File 'ext/openssl/ossl_pkey_ec.c', line 1131

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)


1120
1121
1122
1123
# File 'ext/openssl/ossl_pkey_ec.c', line 1120

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)


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

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;
}