示例#1
0
asn1_error_code asn1_encode_principal_name(asn1buf *buf, const krb5_principal val, unsigned int *retlen)
{
  asn1_setup();
  int n;

  if (val == NULL || val->data == NULL) return ASN1_MISSING_FIELD;

  for(n = (int) ((val->length)-1); n >= 0; n--){
    if (val->data[n].length &&
	val->data[n].data == NULL)
	    return ASN1_MISSING_FIELD;
    retval = asn1_encode_generalstring(buf,
				       (val->data)[n].length,
				       (val->data)[n].data,
				       &length);
    if(retval) return retval;
    sum += length;
  }
  asn1_makeseq();
  retval = asn1_make_etag(buf,CONTEXT_SPECIFIC,1,sum,&length);
  if(retval) return retval;
  sum += length;

  asn1_addfield(val->type,0,asn1_encode_integer);

  asn1_makeseq();

  asn1_cleanup();
}
示例#2
0
krb5_error_code encode_krb5_authenticator(const krb5_authenticator *rep, krb5_data **code)
{
  krb5_setup();

  /* authorization-data[8]	AuthorizationData OPTIONAL */
  if(rep->authorization_data != NULL &&
     rep->authorization_data[0] != NULL){
    retval = asn1_encode_authorization_data(buf, (const krb5_authdata **)
					    rep->authorization_data,
					    &length);
    if(retval){
      asn1buf_destroy(&buf);
      return retval; }
    sum += length;
    retval = asn1_make_etag(buf,CONTEXT_SPECIFIC,8,length,&length);
    if(retval){
      asn1buf_destroy(&buf);
      return retval; }
    sum += length;
  }

  /* seq-number[7]		INTEGER OPTIONAL */
  if(rep->seq_number != 0)
    krb5_addfield(rep->seq_number,7,asn1_encode_unsigned_integer);

  /* subkey[6]			EncryptionKey OPTIONAL */
  if(rep->subkey != NULL)
    krb5_addfield(rep->subkey,6,asn1_encode_encryption_key);

  /* ctime[5]			KerberosTime */
  krb5_addfield(rep->ctime,5,asn1_encode_kerberos_time);

  /* cusec[4]			INTEGER */
  krb5_addfield(rep->cusec,4,asn1_encode_integer);

  /* cksum[3]			Checksum OPTIONAL */
  if(rep->checksum != NULL)
    krb5_addfield(rep->checksum,3,asn1_encode_checksum);

  /* cname[2]			PrincipalName */
  krb5_addfield(rep->client,2,asn1_encode_principal_name);

  /* crealm[1]			Realm */
  krb5_addfield(rep->client,1,asn1_encode_realm);

  /* authenticator-vno[0]	INTEGER */
  krb5_addfield(KVNO,0,asn1_encode_integer);

  /* Authenticator ::= [APPLICATION 2] SEQUENCE */
  krb5_makeseq();
  krb5_apptag(2);

  krb5_cleanup();
}
示例#3
0
asn1_error_code
krb5int_asn1_encode_a_thing(asn1buf *buf, const void *val,
                            const struct atype_info *a, unsigned int *retlen)
{
    switch (a->type) {
    case atype_fn:
        assert(a->enc != NULL);
        return a->enc(buf, val, retlen);
    case atype_sequence:
        assert(a->seq != NULL);
        return just_encode_sequence(buf, val, a->seq, retlen);
    case atype_ptr:
        assert(a->basetype != NULL);
        return krb5int_asn1_encode_a_thing(buf, LOADPTR(val, a),
                                           a->basetype, retlen);
    case atype_field:
        assert(a->field != NULL);
        return encode_a_field(buf, val, a->field, retlen);
    case atype_nullterm_sequence_of:
    case atype_nonempty_nullterm_sequence_of:
        assert(a->basetype != NULL);
        return encode_nullterm_sequence_of(buf, val, a->basetype,
                                           a->type == atype_nullterm_sequence_of,
                                           retlen);
    case atype_tagged_thing:
    {
        asn1_error_code retval;
        unsigned int length, sum = 0;
        retval = krb5int_asn1_encode_a_thing(buf, val, a->basetype, &length);
        if (retval) return retval;
        sum = length;
        retval = asn1_make_etag(buf, a->tagtype, a->tagval, sum, &length);
        if (retval) return retval;
        sum += length;
        *retlen = sum;
        return 0;
    }
    case atype_int:
        assert(a->loadint != NULL);
        return asn1_encode_integer(buf, a->loadint(val), retlen);
    case atype_uint:
        assert(a->loaduint != NULL);
        return asn1_encode_unsigned_integer(buf, a->loaduint(val), retlen);
    case atype_min:
    case atype_max:
    case atype_fn_len:
    default:
        assert(a->type > atype_min);
        assert(a->type < atype_max);
        assert(a->type != atype_fn_len);
        abort();
    }
}
示例#4
0
static asn1_error_code
encode_a_field(asn1buf *buf, const void *val,
               const struct field_info *field,
               unsigned int *retlen)
{
    asn1_error_code retval;
    unsigned int sum = 0;

    if (val == NULL) return ASN1_MISSING_FIELD;

    switch (field->ftype) {
    case field_immediate:
    {
        unsigned int length;

        retval = asn1_encode_integer(buf, (asn1_intmax) field->dataoff,
                                     &length);
        if (retval) return retval;
        sum += length;
        break;
    }
    case field_sequenceof_len:
    {
        const void *dataptr, *lenptr;
        int slen;
        unsigned int length;
        const struct atype_info *a;

        /*
         * The field holds a pointer to the array of objects.  So the
         * address we compute is a pointer-to-pointer, and that's what
         * field->atype must help us dereference.
         */
        dataptr = (const char *)val + field->dataoff;
        lenptr = (const char *)val + field->lenoff;
        assert(field->atype->type == atype_ptr);
        dataptr = LOADPTR(dataptr, field->atype);
        a = field->atype->basetype;
        assert(field->lentype != 0);
        assert(field->lentype->type == atype_int || field->lentype->type == atype_uint);
        assert(sizeof(int) <= sizeof(asn1_intmax));
        assert(sizeof(unsigned int) <= sizeof(asn1_uintmax));
        if (field->lentype->type == atype_int) {
            asn1_intmax xlen = field->lentype->loadint(lenptr);
            if (xlen < 0)
                return EINVAL;
            if ((unsigned int) xlen != (asn1_uintmax) xlen)
                return EINVAL;
            if ((unsigned int) xlen > INT_MAX)
                return EINVAL;
            slen = (int) xlen;
        } else {
            asn1_uintmax xlen = field->lentype->loaduint(lenptr);
            if ((unsigned int) xlen != xlen)
                return EINVAL;
            if (xlen > INT_MAX)
                return EINVAL;
            slen = (int) xlen;
        }
        if (slen != 0 && dataptr == NULL)
            return ASN1_MISSING_FIELD;
        retval = encode_sequence_of(buf, slen, dataptr, a, &length);
        if (retval) return retval;
        sum += length;
        break;
    }
    case field_normal:
    {
        const void *dataptr;
        const struct atype_info *a;
        unsigned int length;

        dataptr = (const char *)val + field->dataoff;

        a = field->atype;
        assert(a->type != atype_fn_len);
        retval = krb5int_asn1_encode_a_thing(buf, dataptr, a, &length);
        if (retval) {
            return retval;
        }
        sum += length;
        break;
    }
    case field_string:
    {
        const void *dataptr, *lenptr;
        const struct atype_info *a;
        size_t slen;
        unsigned int length;

        dataptr = (const char *)val + field->dataoff;
        lenptr = (const char *)val + field->lenoff;

        a = field->atype;
        assert(a->type == atype_fn_len);
        assert(field->lentype != 0);
        assert(field->lentype->type == atype_int || field->lentype->type == atype_uint);
        assert(sizeof(int) <= sizeof(asn1_intmax));
        assert(sizeof(unsigned int) <= sizeof(asn1_uintmax));
        if (field->lentype->type == atype_int) {
            asn1_intmax xlen = field->lentype->loadint(lenptr);
            if (xlen < 0)
                return EINVAL;
            if ((size_t) xlen != (asn1_uintmax) xlen)
                return EINVAL;
            slen = (size_t) xlen;
        } else {
            asn1_uintmax xlen = field->lentype->loaduint(lenptr);
            if ((size_t) xlen != xlen)
                return EINVAL;
            slen = (size_t) xlen;
        }

        dataptr = LOADPTR(dataptr, a);
        if (slen == SIZE_MAX)
            /* Error - negative or out of size_t range.  */
            return EINVAL;
        if (dataptr == NULL && slen != 0)
            return ASN1_MISSING_FIELD;
        /*
         * Currently our string encoders want "unsigned int" for
         * lengths.
         */
        if (slen != (unsigned int) slen)
            return EINVAL;
        assert(a->enclen != NULL);
        retval = a->enclen(buf, (unsigned int) slen, dataptr, &length);
        if (retval) {
            return retval;
        }
        sum += length;
        break;
    }
    default:
        assert(field->ftype > field_min);
        assert(field->ftype < field_max);
        assert(__LINE__ == 0);
        abort();
    }
    if (field->tag >= 0) {
        unsigned int length;
        retval = asn1_make_etag(buf, CONTEXT_SPECIFIC, field->tag, sum,
                                &length);
        if (retval) {
            return retval;
        }
        sum += length;
    }
    *retlen = sum;
    return 0;
}