Example #1
0
File: pkcs7.c Project: ares89/vlc
/* Decodes the PKCS #7 signed data, and returns an ASN1_TYPE, 
 * which holds them. If raw is non null then the raw decoded
 * data are copied (they are locally allocated) there.
 */
static int
_decode_pkcs7_signed_data (ASN1_TYPE pkcs7, ASN1_TYPE * sdata,
                           gnutls_datum_t * raw)
{
  char oid[MAX_OID_SIZE];
  ASN1_TYPE c2;
  opaque *tmp = NULL;
  int tmp_size, len, result;

  len = sizeof (oid) - 1;
  result = asn1_read_value (pkcs7, "contentType", oid, &len);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      return _gnutls_asn2err (result);
    }

  if (strcmp (oid, SIGNED_DATA_OID) != 0)
    {
      gnutls_assert ();
      _gnutls_x509_log ("Unknown PKCS7 Content OID '%s'\n", oid);
      return GNUTLS_E_UNKNOWN_PKCS_CONTENT_TYPE;
    }

  if ((result = asn1_create_element
       (_gnutls_get_pkix (), "PKIX1.pkcs-7-SignedData", &c2)) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      return _gnutls_asn2err (result);
    }

  /* the Signed-data has been created, so
   * decode them.
   */
  tmp_size = 0;
  result = asn1_read_value (pkcs7, "content", NULL, &tmp_size);
  if (result != ASN1_MEM_ERROR)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  tmp = gnutls_malloc (tmp_size);
  if (tmp == NULL)
    {
      gnutls_assert ();
      result = GNUTLS_E_MEMORY_ERROR;
      goto cleanup;
    }

  result = asn1_read_value (pkcs7, "content", tmp, &tmp_size);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  /* tmp, tmp_size hold the data and the size of the CertificateSet structure
   * actually the ANY stuff.
   */

  /* Step 1. In case of a signed structure extract certificate set.
   */

  result = asn1_der_decoding (&c2, tmp, tmp_size, NULL);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  if (raw == NULL)
    {
      gnutls_free (tmp);
    }
  else
    {
      raw->data = tmp;
      raw->size = tmp_size;
    }

  *sdata = c2;

  return 0;

cleanup:
  if (c2)
    asn1_delete_structure (&c2);
  gnutls_free (tmp);
  return result;
}
Example #2
0
/* Converts a PKCS #8 private key info to
 * a PKCS #8 EncryptedPrivateKeyInfo.
 */
static int
encode_to_pkcs8_key(schema_id schema, const gnutls_datum_t * der_key,
		    const char *password, ASN1_TYPE * out)
{
	int result;
	gnutls_datum_t key = { NULL, 0 };
	gnutls_datum_t tmp = { NULL, 0 };
	ASN1_TYPE pkcs8_asn = ASN1_TYPE_EMPTY;
	struct pbkdf2_params kdf_params;
	struct pbe_enc_params enc_params;
	const struct pkcs_cipher_schema_st *s;

	s = _gnutls_pkcs_schema_get(schema);
	if (s == NULL || s->decrypt_only) {
		return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
	}

	if ((result =
	     asn1_create_element(_gnutls_get_pkix(),
				 "PKIX1.pkcs-8-EncryptedPrivateKeyInfo",
				 &pkcs8_asn)) != ASN1_SUCCESS) {
		gnutls_assert();
		return _gnutls_asn2err(result);
	}

	/* Write the encryption schema OID
	 */
	result =
	    asn1_write_value(pkcs8_asn, "encryptionAlgorithm.algorithm",
			     s->write_oid, 1);

	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	/* Generate a symmetric key.
	 */

	result =
	    _gnutls_pkcs_generate_key(schema, password, &kdf_params, &enc_params, &key);
	if (result < 0) {
		gnutls_assert();
		goto error;
	}

	result =
	    _gnutls_pkcs_write_schema_params(schema, pkcs8_asn,
				"encryptionAlgorithm.parameters",
				&kdf_params, &enc_params);
	if (result < 0) {
		gnutls_assert();
		goto error;
	}

	/* Parameters have been encoded. Now
	 * encrypt the Data.
	 */
	result = _gnutls_pkcs_raw_encrypt_data(der_key, &enc_params, &key, &tmp);
	if (result < 0) {
		gnutls_assert();
		goto error;
	}

	/* write the encrypted data.
	 */
	result =
	    asn1_write_value(pkcs8_asn, "encryptedData", tmp.data,
			     tmp.size);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	_gnutls_free_datum(&tmp);
	_gnutls_free_key_datum(&key);

	*out = pkcs8_asn;

	return 0;

      error:
	_gnutls_free_key_datum(&key);
	_gnutls_free_datum(&tmp);
	asn1_delete_structure2(&pkcs8_asn, ASN1_DELETE_FLAG_ZEROIZE);
	return result;
}
Example #3
0
static
int pkcs8_key_info(const gnutls_datum_t * raw_key,
		   const struct pkcs_cipher_schema_st **p,
		   struct pbkdf2_params *kdf_params,
		   char **oid)
{
	int result, len;
	char enc_oid[MAX_OID_SIZE*2];
	int params_start, params_end, params_len;
	struct pbe_enc_params enc_params;
	schema_id schema;
	ASN1_TYPE pkcs8_asn = ASN1_TYPE_EMPTY;

	memset(&enc_params, 0, sizeof(enc_params));

	result = check_for_decrypted(raw_key);
	if (result == 0)
		return GNUTLS_E_INVALID_REQUEST;

	if ((result =
	     asn1_create_element(_gnutls_get_pkix(),
				 "PKIX1.pkcs-8-EncryptedPrivateKeyInfo",
				 &pkcs8_asn)) != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	result =
	    _asn1_strict_der_decode(&pkcs8_asn, raw_key->data, raw_key->size,
			      NULL);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	/* Check the encryption schema OID
	 */
	len = sizeof(enc_oid);
	result =
	    asn1_read_value(pkcs8_asn, "encryptionAlgorithm.algorithm",
			    enc_oid, &len);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		goto error;
	}

	if (oid) {
		*oid = gnutls_strdup(enc_oid);
	}

	if ((result = _gnutls_check_pkcs_cipher_schema(enc_oid)) < 0) {
		gnutls_assert();
		goto error;
	}

	schema = result;

	/* Get the DER encoding of the parameters.
	 */
	result =
	    asn1_der_decoding_startEnd(pkcs8_asn, raw_key->data,
				       raw_key->size,
				       "encryptionAlgorithm.parameters",
				       &params_start, &params_end);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}
	params_len = params_end - params_start + 1;

	result =
	    _gnutls_read_pkcs_schema_params(&schema, NULL,
				    &raw_key->data[params_start],
				    params_len, kdf_params, &enc_params);

	if (result < 0) {
		gnutls_assert();
		if (oid && enc_params.pbes2_oid[0] != 0) {
			snprintf(enc_oid, sizeof(enc_oid), "%s/%s", *oid, enc_params.pbes2_oid);
			gnutls_free(*oid);
			*oid = gnutls_strdup(enc_oid);
		}
		goto error;
	}

	*p = _gnutls_pkcs_schema_get(schema);
	if (*p == NULL) {
		gnutls_assert();
		result = GNUTLS_E_UNKNOWN_CIPHER_TYPE;
		goto error;
	}

	result = 0;

      error:
	asn1_delete_structure2(&pkcs8_asn, ASN1_DELETE_FLAG_ZEROIZE);
	return result;
}
Example #4
0
/**
 * gnutls_x509_crl_get_authority_key_id:
 * @crl: should contain a #gnutls_x509_crl_t structure
 * @ret: The place where the identifier will be copied
 * @ret_size: Holds the size of the result field.
 * @critical: will be non zero if the extension is marked as critical
 *   (may be null)
 *
 * This function will return the CRL authority's key identifier.  This
 * is obtained by the X.509 Authority Key identifier extension field
 * (2.5.29.35).  Note that this function only returns the
 * keyIdentifier field of the extension.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a
 *   negative value in case of an error.
 *
 * Since: 2.8.0
 **/
int
gnutls_x509_crl_get_authority_key_id (gnutls_x509_crl_t crl, void *ret,
                                      size_t * ret_size,
                                      unsigned int *critical)
{
  int result, len;
  gnutls_datum_t id;
  ASN1_TYPE c2 = ASN1_TYPE_EMPTY;

  if (crl == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }


  if (ret)
    memset (ret, 0, *ret_size);
  else
    *ret_size = 0;

  if ((result =
       _gnutls_x509_crl_get_extension (crl, "2.5.29.35", 0, &id,
                                       critical)) < 0)
    {
      return result;
    }

  if (id.size == 0 || id.data == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
    }

  result = asn1_create_element
    (_gnutls_get_pkix (), "PKIX1.AuthorityKeyIdentifier", &c2);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      _gnutls_free_datum (&id);
      return _gnutls_asn2err (result);
    }

  result = asn1_der_decoding (&c2, id.data, id.size, NULL);
  _gnutls_free_datum (&id);

  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      asn1_delete_structure (&c2);
      return _gnutls_asn2err (result);
    }

  len = *ret_size;
  result = asn1_read_value (c2, "keyIdentifier", ret, &len);

  *ret_size = len;
  asn1_delete_structure (&c2);

  if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
    {
      return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
    }

  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      return _gnutls_asn2err (result);
    }

  return 0;
}
Example #5
0
static int
decode_private_key_info(const gnutls_datum_t * der,
			gnutls_x509_privkey_t pkey)
{
	int result, len;
	char oid[MAX_OID_SIZE];
	ASN1_TYPE pkcs8_asn = ASN1_TYPE_EMPTY;
	gnutls_datum_t sder;
	int ret;

	if ((result =
	     asn1_create_element(_gnutls_get_pkix(),
				 "PKIX1.pkcs-8-PrivateKeyInfo",
				 &pkcs8_asn)) != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	result = _asn1_strict_der_decode(&pkcs8_asn, der->data, der->size, NULL);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	/* Check the private key algorithm OID
	 */
	len = sizeof(oid);
	result =
	    asn1_read_value(pkcs8_asn, "privateKeyAlgorithm.algorithm",
			    oid, &len);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	pkey->params.algo = gnutls_oid_to_pk(oid);
	if (pkey->params.algo == GNUTLS_PK_UNKNOWN) {
		gnutls_assert();
		_gnutls_debug_log
		    ("PKCS #8 private key OID '%s' is unsupported.\n",
		     oid);
		result = GNUTLS_E_UNKNOWN_PK_ALGORITHM;
		goto error;
	}

	/* Get the DER encoding of the actual private key.
	 */

	switch(pkey->params.algo) {
		case GNUTLS_PK_RSA:
			result = _decode_pkcs8_rsa_key(pkcs8_asn, pkey);
			break;
		case GNUTLS_PK_RSA_PSS:
			result = _decode_pkcs8_rsa_pss_key(pkcs8_asn, pkey);
			break;
		case GNUTLS_PK_DSA:
			result = _decode_pkcs8_dsa_key(pkcs8_asn, pkey);
			break;
		case GNUTLS_PK_ECDSA:
			result = _decode_pkcs8_ecc_key(pkcs8_asn, pkey);
			break;
		case GNUTLS_PK_EDDSA_ED25519:
			result = _decode_pkcs8_eddsa_key(pkcs8_asn, pkey, oid);
			break;
		case GNUTLS_PK_GOST_01:
		case GNUTLS_PK_GOST_12_256:
		case GNUTLS_PK_GOST_12_512:
			result = _decode_pkcs8_gost_key(pkcs8_asn,
							pkey, pkey->params.algo);
			break;
		default:
			result = gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
			goto error;
	}

	if (result < 0) {
		gnutls_assert();
		goto error;
	}

	/* check for provable parameters attribute */
	ret = _x509_parse_attribute(pkcs8_asn, "attributes", OID_ATTR_PROV_SEED, 0, 1, &sder);
	if (ret >= 0) { /* ignore it when not being present */
		ret = _x509_decode_provable_seed(pkey, &sder);
		gnutls_free(sder.data);
		if (ret < 0) {
			gnutls_assert();
		}
	}

	result = 0;

error:
	asn1_delete_structure2(&pkcs8_asn, ASN1_DELETE_FLAG_ZEROIZE);
	return result;

}
Example #6
0
/* Writes the digest information and the digest in a DER encoded
 * structure. The digest info is allocated and stored into the info structure.
 */
int
encode_ber_digest_info(const mac_entry_st * e,
			const gnutls_datum_t * digest,
			gnutls_datum_t * output)
{
	ASN1_TYPE dinfo = ASN1_TYPE_EMPTY;
	int result;
	const char *algo;
	uint8_t *tmp_output;
	int tmp_output_size;

	algo = _gnutls_x509_mac_to_oid(e);
	if (algo == NULL) {
		gnutls_assert();
		_gnutls_debug_log("Hash algorithm: %d has no OID\n",
				  e->id);
		return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
	}

	if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
					  "GNUTLS.DigestInfo",
					  &dinfo)) != ASN1_SUCCESS) {
		gnutls_assert();
		return _gnutls_asn2err(result);
	}

	result =
	    asn1_write_value(dinfo, "digestAlgorithm.algorithm", algo, 1);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		asn1_delete_structure(&dinfo);
		return _gnutls_asn2err(result);
	}

	/* Write an ASN.1 NULL in the parameters field.  This matches RFC
	   3279 and RFC 4055, although is arguable incorrect from a historic
	   perspective (see those documents for more information).
	   Regardless of what is correct, this appears to be what most
	   implementations do.  */
	result = asn1_write_value(dinfo, "digestAlgorithm.parameters",
				  ASN1_NULL, ASN1_NULL_SIZE);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		asn1_delete_structure(&dinfo);
		return _gnutls_asn2err(result);
	}

	result =
	    asn1_write_value(dinfo, "digest", digest->data, digest->size);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		asn1_delete_structure(&dinfo);
		return _gnutls_asn2err(result);
	}

	tmp_output_size = 0;
	result = asn1_der_coding(dinfo, "", NULL, &tmp_output_size, NULL);
	if (result != ASN1_MEM_ERROR) {
		gnutls_assert();
		asn1_delete_structure(&dinfo);
		return _gnutls_asn2err(result);
	}

	tmp_output = gnutls_malloc(tmp_output_size);
	if (tmp_output == NULL) {
		gnutls_assert();
		asn1_delete_structure(&dinfo);
		return GNUTLS_E_MEMORY_ERROR;
	}

	result =
	    asn1_der_coding(dinfo, "", tmp_output, &tmp_output_size, NULL);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		asn1_delete_structure(&dinfo);
		return _gnutls_asn2err(result);
	}

	asn1_delete_structure(&dinfo);

	output->size = tmp_output_size;
	output->data = tmp_output;

	return 0;
}
Example #7
0
/**
 * gnutls_decode_ber_digest_info:
 * @info: an RSA BER encoded DigestInfo structure
 * @hash: will contain the hash algorithm of the structure
 * @digest: will contain the hash output of the structure
 * @digest_size: will contain the hash size of the structure; initially must hold the maximum size of @digest
 *
 * This function will parse an RSA PKCS#1 1.5 DigestInfo structure
 * and report the hash algorithm used as well as the digest data.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
 *   an error code is returned.
 *
 * Since: 3.5.0
 *
 **/
int
gnutls_decode_ber_digest_info(const gnutls_datum_t * info,
		       gnutls_digest_algorithm_t * hash,
		       unsigned char * digest, unsigned int *digest_size)
{
	ASN1_TYPE dinfo = ASN1_TYPE_EMPTY;
	int result;
	char str[MAX(MAX_OID_SIZE, MAX_HASH_SIZE)];
	int len;

	if ((result = asn1_create_element(_gnutls_get_gnutls_asn(),
					  "GNUTLS.DigestInfo",
					  &dinfo)) != ASN1_SUCCESS) {
		gnutls_assert();
		return _gnutls_asn2err(result);
	}

	result = asn1_der_decoding(&dinfo, info->data, info->size, NULL);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		asn1_delete_structure(&dinfo);
		return _gnutls_asn2err(result);
	}

	len = sizeof(str) - 1;
	result =
	    asn1_read_value(dinfo, "digestAlgorithm.algorithm", str, &len);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		asn1_delete_structure(&dinfo);
		return _gnutls_asn2err(result);
	}

	*hash = gnutls_oid_to_digest(str);

	if (*hash == GNUTLS_DIG_UNKNOWN) {

		_gnutls_debug_log("verify.c: HASH OID: %s\n", str);

		gnutls_assert();
		asn1_delete_structure(&dinfo);
		return GNUTLS_E_UNKNOWN_HASH_ALGORITHM;
	}

	len = sizeof(str) - 1;
	result =
	    asn1_read_value(dinfo, "digestAlgorithm.parameters", str,
			    &len);
	/* To avoid permitting garbage in the parameters field, either the
	   parameters field is not present, or it contains 0x05 0x00. */
	if (!(result == ASN1_ELEMENT_NOT_FOUND ||
	      (result == ASN1_SUCCESS && len == ASN1_NULL_SIZE &&
	       memcmp(str, ASN1_NULL, ASN1_NULL_SIZE) == 0))) {
		gnutls_assert();
		asn1_delete_structure(&dinfo);
		return GNUTLS_E_ASN1_GENERIC_ERROR;
	}

	len = *digest_size;
	result = asn1_read_value(dinfo, "digest", digest, &len);

	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		*digest_size = len;
		asn1_delete_structure(&dinfo);
		return _gnutls_asn2err(result);
	}

	*digest_size = len;
	asn1_delete_structure(&dinfo);

	return 0;
}
Example #8
0
static int
create_platf_manufacturer_info(const char *manufacturer,
                               const char *platf_model,
                               const char *platf_version,
                               gnutls_datum_t *asn1)
{
    ASN1_TYPE at = ASN1_TYPE_EMPTY;
    int err;

    err = asn_init();
    if (err != ASN1_SUCCESS) {
        goto cleanup;
    }

    err = asn1_create_element(_tpm_asn, "TPM.PlatformManufacturerInfo", &at);
    if (err != ASN1_SUCCESS) {
        fprintf(stderr, "asn1_create_element error: %d\n", err);
        goto cleanup;
    }

    err = asn1_write_value(at, "platformManufacturer.id", "2.23.133.2.4", 0);
    if (err != ASN1_SUCCESS) {
        fprintf(stderr, "b1. asn1_write_value error: %d\n", err);
        goto cleanup;
    }

    err = asn1_write_value(at, "platformManufacturer.manufacturer",
                           manufacturer, 0);
    if (err != ASN1_SUCCESS) {
        fprintf(stderr, "b2. asn1_write_value error: %d\n", err);
        goto cleanup;
    }
    
    err = asn1_write_value(at, "platformModel.id", "2.23.133.2.5", 0);
    if (err != ASN1_SUCCESS) {
        fprintf(stderr, "b3. asn1_write_value error: %d\n", err);
        goto cleanup;
    }

    err = asn1_write_value(at, "platformModel.model", manufacturer, 0);
    if (err != ASN1_SUCCESS) {
        fprintf(stderr, "b4. asn1_write_value error: %d\n", err);
        goto cleanup;
    }
    
    err = asn1_write_value(at, "platformVersion.id", "2.23.133.2.6", 0);
    if (err != ASN1_SUCCESS) {
        fprintf(stderr, "b5. asn1_write_value error: %d\n", err);
        goto cleanup;
    }

    err = asn1_write_value(at, "platformVersion.version", manufacturer, 0);
    if (err != ASN1_SUCCESS) {
        fprintf(stderr, "b6. asn1_write_value error: %d\n", err);
        goto cleanup;
    }
    
    /* determine needed size of byte array */
    asn1->size = 0;
    err = asn1_der_coding(at, "", NULL, (int *)&asn1->size, NULL);
    if (err != ASN1_MEM_ERROR) {
        fprintf(stderr, "b1. asn1_der_coding error: %d\n", err);
        goto cleanup;
    }
    //fprintf(stderr, "size=%d\n", asn1->size);
    asn1->data = gnutls_malloc(asn1->size + 16);
    err = asn1_der_coding(at, "", asn1->data, (int *)&asn1->size, NULL);

    if (err != ASN1_SUCCESS) {
        fprintf(stderr, "b2. asn1_der_coding error: %d\n", err);
        gnutls_free(asn1->data);
        asn1->data = NULL;
        goto cleanup;
    }

#if 0
    fprintf(stderr, "size=%d\n", asn1->size);
    unsigned int i = 0;
    for (i = 0; i < asn1->size; i++) {
        fprintf(stderr, "%02x ", asn1->data[i]);
    }
    fprintf(stderr, "\n");
#endif

 cleanup:    
    asn1_delete_structure(&at);
    
    return err;
}
Example #9
0
/* Creates and encodes the CRL Distribution points. data_string should be a name
 * and type holds the type of the name.
 * reason_flags should be an or'ed sequence of GNUTLS_CRL_REASON_*.
 *
 */
int
_gnutls_x509_ext_gen_crl_dist_points(gnutls_x509_subject_alt_name_t
                                     type, const void *data,
                                     unsigned int data_size,
                                     unsigned int reason_flags,
                                     gnutls_datum_t * der_ext)
{
    ASN1_TYPE ext = ASN1_TYPE_EMPTY;
    gnutls_datum_t gnames = { NULL, 0 };
    int result;
    uint8_t reasons[2];

    reasons[0] = reason_flags & 0xff;
    reasons[1] = reason_flags >> 8;

    result =
        asn1_create_element(_gnutls_get_pkix(),
                            "PKIX1.CRLDistributionPoints", &ext);
    if (result != ASN1_SUCCESS) {
        gnutls_assert();
        result = _gnutls_asn2err(result);
        goto cleanup;
    }

    result = asn1_write_value(ext, "", "NEW", 1);
    if (result != ASN1_SUCCESS) {
        gnutls_assert();
        result = _gnutls_asn2err(result);
        goto cleanup;
    }

    if (reason_flags) {
        result =
            asn1_write_value(ext, "?LAST.reasons", reasons, 9);
        if (result != ASN1_SUCCESS) {
            gnutls_assert();
            result = _gnutls_asn2err(result);
            goto cleanup;
        }
    } else {
        result = asn1_write_value(ext, "?LAST.reasons", NULL, 0);
        if (result != ASN1_SUCCESS) {
            gnutls_assert();
            result = _gnutls_asn2err(result);
            goto cleanup;
        }
    }

    result = asn1_write_value(ext, "?LAST.cRLIssuer", NULL, 0);
    if (result != ASN1_SUCCESS) {
        gnutls_assert();
        result = _gnutls_asn2err(result);
        goto cleanup;
    }

    /* When used as type CHOICE.
     */
    result =
        asn1_write_value(ext, "?LAST.distributionPoint", "fullName",
                         1);
    if (result != ASN1_SUCCESS) {
        gnutls_assert();
        result = _gnutls_asn2err(result);
        goto cleanup;
    }
#if 0
    /* only needed in old code (where defined as SEQUENCE OF) */
    asn1_write_value(ext,
                     "?LAST.distributionPoint.nameRelativeToCRLIssuer",
                     NULL, 0);
#endif

    result =
        write_new_general_name(ext, "?LAST.distributionPoint.fullName",
                               type, data, data_size);
    if (result < 0) {
        gnutls_assert();
        goto cleanup;
    }

    result = _gnutls_x509_der_encode(ext, "", der_ext, 0);

    if (result < 0) {
        gnutls_assert();
        goto cleanup;
    }

    result = 0;

cleanup:
    _gnutls_free_datum(&gnames);
    asn1_delete_structure(&ext);

    return result;
}
Example #10
0
int _gnutls_krb5_principal_to_der(const char *name, gnutls_datum_t * der)
{
	int ret, result;
	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
	krb5_principal_data *princ;
	unsigned i;

	princ = name_to_principal(name);
	if (princ == NULL) {
		gnutls_assert();
		ret = GNUTLS_E_PARSING_ERROR;
		goto cleanup;
	}

	result =
	    asn1_create_element(_gnutls_get_gnutls_asn(),
				"GNUTLS.KRB5PrincipalName", &c2);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		ret = _gnutls_asn2err(result);
		goto cleanup;
	}

	result =
	    asn1_write_value(c2, "realm", princ->realm, strlen(princ->realm));
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		ret = _gnutls_asn2err(result);
		goto cleanup;
	}

	result =
	    asn1_write_value(c2, "principalName.name-type", &princ->type, 1);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		ret = _gnutls_asn2err(result);
		goto cleanup;
	}

	for (i = 0; i < princ->length; i++) {
		result =
		    asn1_write_value(c2, "principalName.name-string", "NEW", 1);
		if (result != ASN1_SUCCESS) {
			gnutls_assert();
			ret = _gnutls_asn2err(result);
			goto cleanup;
		}

		result =
		    asn1_write_value(c2,
				     "principalName.name-string.?LAST",
				     princ->data[i], strlen(princ->data[i]));
		if (result != ASN1_SUCCESS) {
			gnutls_assert();
			ret = _gnutls_asn2err(result);
			goto cleanup;
		}
	}

	ret = _gnutls_x509_der_encode(c2, "", der, 0);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	ret = 0;
 cleanup:
	cleanup_principal(princ);
	asn1_delete_structure(&c2);
	return ret;
}
Example #11
0
static gnutls_pubkey_t
create_rsa_from_modulus(unsigned char *modulus, unsigned int modulus_len,
                        uint32_t exponent)
{
    unsigned char exp_array[4];
    uint32_t exponent_no = htonl(exponent);
    gnutls_pubkey_t rsa = NULL;
    gnutls_datum_t mod;
    gnutls_datum_t exp = {
        .data = exp_array,
        .size = sizeof(exp_array),
    };
    int err;

    memcpy(exp_array, &exponent_no, sizeof(exp_array));

    err = gnutls_pubkey_init(&rsa);
    if (err < 0) {
        fprintf(stderr, "Could not initialized public key structure : %s\n",
                gnutls_strerror(err));
        return NULL;
    }

    mod.data = modulus;
    mod.size = modulus_len;

    err = gnutls_pubkey_import_rsa_raw(rsa, &mod, &exp);
    if (err < 0) {
        fprintf(stderr, "Could not set modulus and exponent on RSA key : %s\n",
                gnutls_strerror(err));
        gnutls_pubkey_deinit(rsa);
        rsa = NULL;
    }

    return rsa;
}

static int
asn_init()
{
    static bool inited;
    int err;

    if (inited)
        return ASN1_SUCCESS;

    err = asn1_array2tree(tpm_asn1_tab, &_tpm_asn, NULL);
    if (err != ASN1_SUCCESS) {
        fprintf(stderr, "array2tree error: %d", err);
        goto cleanup;
    }

    inited = true;

cleanup:

    return err;
}

static int
create_tpm_manufacturer_info(const char *manufacturer,
                             const char *tpm_model,
                             const char *tpm_version,
                             gnutls_datum_t *asn1)
{
    ASN1_TYPE at = ASN1_TYPE_EMPTY;
    int err;

    err = asn_init();
    if (err != ASN1_SUCCESS) {
        goto cleanup;
    }

    err = asn1_create_element(_tpm_asn, "TPM.TPMManufacturerInfo", &at);
    if (err != ASN1_SUCCESS) {
        fprintf(stderr, "asn1_create_element error: %d\n", err);
        goto cleanup;
    }

    err = asn1_write_value(at, "tpmManufacturer.id", "2.23.133.2.1", 0);
    if (err != ASN1_SUCCESS) {
        fprintf(stderr, "1. asn1_write_value error: %d\n", err);
        goto cleanup;
    }

    err = asn1_write_value(at, "tpmManufacturer.manufacturer",
                           manufacturer, 0);
    if (err != ASN1_SUCCESS) {
        fprintf(stderr, "2. asn1_write_value error: %d\n", err);
        goto cleanup;
    }
    
    err = asn1_write_value(at, "tpmModel.id", "2.23.133.2.2", 0);
    if (err != ASN1_SUCCESS) {
        fprintf(stderr, "3. asn1_write_value error: %d\n", err);
        goto cleanup;
    }

    err = asn1_write_value(at, "tpmModel.model", manufacturer, 0);
    if (err != ASN1_SUCCESS) {
        fprintf(stderr, "4. asn1_write_value error: %d\n", err);
        goto cleanup;
    }
    
    err = asn1_write_value(at, "tpmVersion.id", "2.23.133.2.3", 0);
    if (err != ASN1_SUCCESS) {
        fprintf(stderr, "5. asn1_write_value error: %d\n", err);
        goto cleanup;
    }

    err = asn1_write_value(at, "tpmVersion.version", manufacturer, 0);
    if (err != ASN1_SUCCESS) {
        fprintf(stderr, "6. asn1_write_value error: %d\n", err);
        goto cleanup;
    }
    
    /* determine needed size of byte array */
    asn1->size = 0;
    err = asn1_der_coding(at, "", NULL, (int *)&asn1->size, NULL);
    if (err != ASN1_MEM_ERROR) {
        fprintf(stderr, "1. asn1_der_coding error: %d\n", err);
        goto cleanup;
    }
    //fprintf(stderr, "size=%d\n", asn1->size);
    asn1->data = gnutls_malloc(asn1->size + 16);
    err = asn1_der_coding(at, "", asn1->data, (int *)&asn1->size, NULL);

    if (err != ASN1_SUCCESS) {
        fprintf(stderr, "2. asn1_der_coding error: %d\n", err);
        gnutls_free(asn1->data);
        asn1->data = NULL;
        goto cleanup;
    }

#if 0
    fprintf(stderr, "size=%d\n", asn1->size);
    unsigned int i = 0;
    for (i = 0; i < asn1->size; i++) {
        fprintf(stderr, "%02x ", asn1->data[i]);
    }
    fprintf(stderr, "\n");
#endif

 cleanup:    
    asn1_delete_structure(&at);
    
    return err;
}
Example #12
0
int
main (int argc, char *argv[])
{
  int result, verbose = 0;
  asn1_node definitions = NULL;
  asn1_node asn1_element = NULL;
  char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
  const char *treefile = getenv ("ASN1SETOF");
  unsigned i;

  if (argc > 1)
    verbose = 1;

  if (!treefile)
    treefile = "setof.asn";

  if (verbose != 0)
    {
      printf ("\n\n/****************************************/\n");
      printf ("/*     Test sequence : coding-decoding  */\n");
      printf ("/****************************************/\n\n");
    }

  /* Check version */
  if (asn1_check_version ("0.3.3") == NULL)
    printf ("\nLibrary version check ERROR:\n actual version: %s\n\n",
	    asn1_check_version (NULL));

  result = asn1_parser2tree (treefile, &definitions, errorDescription);

  if (result != ASN1_SUCCESS)
    {
      asn1_perror (result);
      printf ("ErrorDescription = %s\n\n", errorDescription);
      exit (1);
    }

  result = asn1_create_element (definitions, "TEST.Set", &asn1_element);
  if (result != ASN1_SUCCESS)
    {
      fprintf (stderr, "asn1_create_element(): ");
      asn1_perror (result);
      exit (1);
    }

  result = asn1_write_value (asn1_element, "", "NEW", 1);
  assert(result == ASN1_SUCCESS);

  result = asn1_write_value (asn1_element, "?LAST.val", "\x00\x02", 2);
  assert(result == ASN1_SUCCESS);

  result = asn1_write_value (asn1_element, "", "NEW", 1);
  assert(result == ASN1_SUCCESS);

  result = asn1_write_value (asn1_element, "?LAST.val", "\x00\x01\x00\x00", 4);
  assert(result == ASN1_SUCCESS);

  result = asn1_write_value (asn1_element, "", "NEW", 1);
  assert(result == ASN1_SUCCESS);

  result = asn1_write_value (asn1_element, "?LAST.val", "\x00\x00\x00\x00", 4);
  assert(result == ASN1_SUCCESS);

  result = asn1_write_value (asn1_element, "", "NEW", 1);
  assert(result == ASN1_SUCCESS);

  result = asn1_write_value (asn1_element, "?LAST.val", "\x00\x00\x00\x02", 4);
  assert(result == ASN1_SUCCESS);

  result = asn1_write_value (asn1_element, "", "NEW", 1);
  assert(result == ASN1_SUCCESS);

  result = asn1_write_value (asn1_element, "?LAST.val", "\x00\x00\x00\x01", 4);
  assert(result == ASN1_SUCCESS);

  result = asn1_write_value (asn1_element, "", "NEW", 1);
  assert(result == ASN1_SUCCESS);

  result = asn1_write_value (asn1_element, "?LAST.val", "\x01\x00\x00\x00", 4);
  assert(result == ASN1_SUCCESS);

  result = asn1_write_value (asn1_element, "", "NEW", 1);
  assert(result == ASN1_SUCCESS);

  result = asn1_write_value (asn1_element, "?LAST.val", "\x01\x01\x00\x00", 4);
  assert(result == ASN1_SUCCESS);

  result = asn1_write_value (asn1_element, "", "NEW", 1);
  assert(result == ASN1_SUCCESS);

  result = asn1_write_value (asn1_element, "?LAST.val", "\x05", 1);
  assert(result == ASN1_SUCCESS);

  result = asn1_write_value (asn1_element, "", "NEW", 1);
  assert(result == ASN1_SUCCESS);

  result = asn1_write_value (asn1_element, "?LAST.val", "\x01", 1);
  assert(result == ASN1_SUCCESS);

  /* Clear the definition structures */

  result = asn1_der_coding (asn1_element, "", data, &data_size, NULL);
  if (result != ASN1_SUCCESS)
    {
      fprintf (stderr, "Encoding error.\n");
      asn1_perror (result);
      exit (1);
    }

  asn1_delete_structure (&asn1_element);
  asn1_delete_structure (&definitions);

  if (data_size != sizeof(expected_der) || memcmp(data, expected_der, data_size) != 0)
    {
      fprintf(stderr, "encoded data differ to expected [%d - %d]!\n", data_size, (int)sizeof(expected_der));
      printf("static unsigned char got[] = {\n");
      for (i=0;i<(unsigned)data_size;i++) {
        printf("0x%.2x, ", (unsigned)data[i]);
        if ((i+1) % 8 == 0)
          printf("\n");
      }
      printf("};\n");

      printf("static unsigned char expected[] = {\n");
      for (i=0;i<(unsigned)sizeof(expected_der);i++) {
        printf("0x%.2x, ", (unsigned)expected_der[i]);
        if ((i+1) % 8 == 0)
          printf("\n");
      }
      printf("};\n");
      exit(1);
    }

  if (verbose)
    printf ("Success\n");
  exit (0);
}
Example #13
0
static int
decode_complex_string(const struct oid_to_string *oentry, void *value,
		      int value_size, gnutls_datum_t * out)
{
	char str[MAX_STRING_LEN], tmpname[128];
	int len = -1, result;
	ASN1_TYPE tmpasn = ASN1_TYPE_EMPTY;
	char asn1_err[ASN1_MAX_ERROR_DESCRIPTION_SIZE] = "";
	unsigned int etype;
	gnutls_datum_t td = {NULL, 0};

	if (oentry->asn_desc == NULL) {
		gnutls_assert();
		return GNUTLS_E_INTERNAL_ERROR;
	}

	if ((result =
	     asn1_create_element(_gnutls_get_pkix(), oentry->asn_desc,
				 &tmpasn)) != ASN1_SUCCESS) {
		gnutls_assert();
		return _gnutls_asn2err(result);
	}

	if ((result =
	     _asn1_strict_der_decode(&tmpasn, value, value_size,
			       asn1_err)) != ASN1_SUCCESS) {
		gnutls_assert();
		_gnutls_debug_log("_asn1_strict_der_decode: %s\n", asn1_err);
		asn1_delete_structure(&tmpasn);
		return _gnutls_asn2err(result);
	}

	/* Read the type of choice.
	 */
	len = sizeof(str) - 1;
	if ((result = asn1_read_value(tmpasn, "", str, &len)) != ASN1_SUCCESS) {	/* CHOICE */
		gnutls_assert();
		asn1_delete_structure(&tmpasn);
		return _gnutls_asn2err(result);
	}

	str[len] = 0;

	/* We set the etype on the strings that may need
	 * some conversion to UTF-8. The INVALID flag indicates
	 * no conversion needed */
	if (strcmp(str, "teletexString") == 0)
		etype = ASN1_ETYPE_TELETEX_STRING;
	else if (strcmp(str, "bmpString") == 0)
		etype = ASN1_ETYPE_BMP_STRING;
	else if (strcmp(str, "universalString") == 0)
		etype = ASN1_ETYPE_UNIVERSAL_STRING;
	else
		etype = ASN1_ETYPE_INVALID;

	_gnutls_str_cpy(tmpname, sizeof(tmpname), str);

	result = _gnutls_x509_read_value(tmpasn, tmpname, &td);
	asn1_delete_structure(&tmpasn);
	if (result < 0)
		return gnutls_assert_val(result);

	if (etype != ASN1_ETYPE_INVALID) {
		result = make_printable_string(etype, &td, out);

		_gnutls_free_datum(&td);

		if (result < 0)
			return gnutls_assert_val(result);
	} else {
		out->data = td.data;
		out->size = td.size;
		/* _gnutls_x509_read_value always null terminates */
	}

	/* Refuse to deal with strings containing NULs. */
	if (strlen((void *) out->data) != (size_t) out->size) {
		_gnutls_free_datum(out);
		return gnutls_assert_val(GNUTLS_E_ASN1_EMBEDDED_NULL_IN_STRING);
	}

	return 0;
}
Example #14
0
static int write_complex_string(ASN1_TYPE asn_struct, const char *where,
				const struct oid_to_string *oentry,
				const uint8_t * data, size_t data_size)
{
	char tmp[128];
	ASN1_TYPE c2;
	int result;
	const char *string_type;
	unsigned int i;

	result =
	    asn1_create_element(_gnutls_get_pkix(), oentry->asn_desc, &c2);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		return _gnutls_asn2err(result);
	}

	tmp[0] = 0;

	string_type = "printableString";

	/* Check if the data is ASN.1 printable, and use
	 * the UTF8 string type if not.
	 */
	for (i = 0; i < data_size; i++) {
		if (!is_printable(data[i])) {
			string_type = "utf8String";
			break;
		}
	}

	/* if the type is a CHOICE then write the
	 * type we'll use.
	 */
	result = asn1_write_value(c2, "", string_type, 1);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	_gnutls_str_cpy(tmp, sizeof(tmp), string_type);

	result = asn1_write_value(c2, tmp, data, data_size);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	result =
	    _gnutls_x509_der_encode_and_copy(c2, "", asn_struct, where, 0);
	if (result < 0) {
		gnutls_assert();
		goto error;
	}

	result = 0;

      error:
	asn1_delete_structure(&c2);
	return result;
}
Example #15
0
static int      negotiate(smb_session *s, const char *domain)
{
    smb_message           *msg = NULL;
    smb_session_xsec_req  req;
    smb_buffer            ntlm;
    ASN1_TYPE             token;
    int                   res, der_size = 128;
    char                  der[128], err_desc[ASN1_MAX_ERROR_DESCRIPTION_SIZE];

    msg = smb_message_new(SMB_CMD_SETUP);
    if (!msg)
        return DSM_ERROR_GENERIC;

    // this struct will be set at the end when we know the payload size
    SMB_MSG_ADVANCE_PKT(msg, smb_session_xsec_req);

    asn1_create_element(s->spnego_asn1, "SPNEGO.GSSAPIContextToken", &token);

    res = asn1_write_value(token, "thisMech", spnego_oid, 1);
    if (res != ASN1_SUCCESS) goto error;
    res = asn1_write_value(token, "spnego", "negTokenInit", 1);
    if (res != ASN1_SUCCESS) goto error;
    res = asn1_write_value(token, "spnego.negTokenInit.mechTypes", "NEW", 1);
    if (res != ASN1_SUCCESS) goto error;
    res = asn1_write_value(token, "spnego.negTokenInit.mechTypes.?1", ntlmssp_oid, 1);
    if (res != ASN1_SUCCESS) goto error;
    res = asn1_write_value(token, "spnego.negTokenInit.reqFlags", NULL, 0);
    if (res != ASN1_SUCCESS) goto error;
    res = asn1_write_value(token, "spnego.negTokenInit.mechListMIC", NULL, 0);
    if (res != ASN1_SUCCESS) goto error;

    smb_ntlmssp_negotiate(domain, domain, &ntlm);
    res = asn1_write_value(token, "spnego.negTokenInit.mechToken", ntlm.data,
                           ntlm.size);
    smb_buffer_free(&ntlm);
    if (res != ASN1_SUCCESS) goto error;

    res = asn1_der_coding(token, "", der, &der_size, err_desc);
    if (res != ASN1_SUCCESS)
    {
        smb_message_destroy(msg);
        BDSM_dbg("Encoding error: %s", err_desc);
        return DSM_ERROR_GENERIC;
    }

    smb_message_append(msg, der, der_size);
    smb_message_put_utf16(msg, SMB_OS, strlen(SMB_OS));
    smb_message_put16(msg, 0);
    smb_message_put_utf16(msg, SMB_LANMAN, strlen(SMB_LANMAN));
    smb_message_put16(msg, 0);
    smb_message_put16(msg, 0);

    SMB_MSG_INIT_PKT_ANDX(req);
    req.wct              = 12;
    req.max_buffer       = SMB_SESSION_MAX_BUFFER;
    req.mpx_count        = 16;
    req.vc_count         = 1;
    req.caps             = s->srv.caps;
    req.session_key      = s->srv.session_key;
    req.xsec_blob_size = der_size;
    req.payload_size   = msg->cursor - sizeof(smb_session_xsec_req);
    SMB_MSG_INSERT_PKT(msg, 0, req);

    asn1_delete_structure(&token);

    if (!smb_session_send_msg(s, msg))
    {
        smb_message_destroy(msg);
        BDSM_dbg("Unable to send Session Setup AndX (NTLMSSP_NEGOTIATE) message\n");
        return DSM_ERROR_NETWORK;
    }

    smb_message_destroy(msg);
    return DSM_SUCCESS;

error:
    asn1_display_error("smb_session_login negotiate()", res);
    smb_message_destroy(msg);
    return DSM_ERROR_GENERIC;
}
Example #16
0
/* extract the proxyCertInfo from the DER encoded extension
 */
int
_gnutls_x509_ext_extract_proxyCertInfo(int *pathLenConstraint,
                                       char **policyLanguage,
                                       char **policy,
                                       size_t * sizeof_policy,
                                       uint8_t * extnValue,
                                       int extnValueLen)
{
    ASN1_TYPE ext = ASN1_TYPE_EMPTY;
    int result;
    gnutls_datum_t value;

    if ((result = asn1_create_element
                  (_gnutls_get_pkix(), "PKIX1.ProxyCertInfo",
                   &ext)) != ASN1_SUCCESS) {
        gnutls_assert();
        return _gnutls_asn2err(result);
    }

    result = asn1_der_decoding(&ext, extnValue, extnValueLen, NULL);
    if (result != ASN1_SUCCESS) {
        gnutls_assert();
        asn1_delete_structure(&ext);
        return _gnutls_asn2err(result);
    }

    if (pathLenConstraint) {
        result = _gnutls_x509_read_uint(ext, "pCPathLenConstraint",
                                        (unsigned int *)
                                        pathLenConstraint);
        if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
            *pathLenConstraint = -1;
        else if (result != GNUTLS_E_SUCCESS) {
            asn1_delete_structure(&ext);
            return _gnutls_asn2err(result);
        }
    }

    result = _gnutls_x509_read_value(ext, "proxyPolicy.policyLanguage",
                                     &value);
    if (result < 0) {
        gnutls_assert();
        asn1_delete_structure(&ext);
        return result;
    }

    if (policyLanguage)
        *policyLanguage = gnutls_strdup((char *) value.data);

    result =
        _gnutls_x509_read_value(ext, "proxyPolicy.policy", &value);
    if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND) {
        if (policy)
            *policy = NULL;
        if (sizeof_policy)
            *sizeof_policy = 0;
    } else if (result < 0) {
        gnutls_assert();
        asn1_delete_structure(&ext);
        return result;
    } else {
        if (policy)
            *policy = (char *) value.data;
        if (sizeof_policy)
            *sizeof_policy = value.size;
    }

    asn1_delete_structure(&ext);

    return 0;
}
Example #17
0
/* This will encode and write the AttributeTypeAndValue field.
 * 'multi' must be zero if writing an AttributeTypeAndValue, and 1 if Attribute.
 * In all cases only one value is written.
 */
int
_gnutls_x509_encode_and_write_attribute (const char *given_oid,
					 ASN1_TYPE asn1_struct,
					 const char *where,
					 const void *_data,
					 int sizeof_data, int multi)
{
  const char *val_name;
  const opaque *data = _data;
  char tmp[128];
  ASN1_TYPE c2;
  int result;


  /* Find how to encode the data.
   */
  val_name = asn1_find_structure_from_oid (_gnutls_get_pkix (), given_oid);
  if (val_name == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_X509_UNSUPPORTED_OID;
    }

  _gnutls_str_cpy (tmp, sizeof (tmp), "PKIX1.");
  _gnutls_str_cat (tmp, sizeof (tmp), val_name);

  result = asn1_create_element (_gnutls_get_pkix (), tmp, &c2);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      return _gnutls_asn2err (result);
    }

  tmp[0] = 0;

  if ((result = _gnutls_x509_oid_data_choice (given_oid)) > 0)
    {
      char *string_type;
      int i;

      string_type = "printableString";

      /* Check if the data is plain ascii, and use
       * the UTF8 string type if not.
       */
      for (i = 0; i < sizeof_data; i++)
	{
	  if (!isascii (data[i]))
	    {
	      string_type = "utf8String";
	      break;
	    }
	}

      /* if the type is a CHOICE then write the
       * type we'll use.
       */
      result = asn1_write_value (c2, "", string_type, 1);
      if (result != ASN1_SUCCESS)
	{
	  gnutls_assert ();
	  asn1_delete_structure (&c2);
	  return _gnutls_asn2err (result);
	}

      _gnutls_str_cpy (tmp, sizeof (tmp), string_type);
    }

  result = asn1_write_value (c2, tmp, data, sizeof_data);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      asn1_delete_structure (&c2);
      return _gnutls_asn2err (result);
    }


  /* write the data (value)
   */

  _gnutls_str_cpy (tmp, sizeof (tmp), where);
  _gnutls_str_cat (tmp, sizeof (tmp), ".value");

  if (multi != 0)
    {				/* if not writing an AttributeTypeAndValue, but an Attribute */
      _gnutls_str_cat (tmp, sizeof (tmp), "s");	/* values */

      result = asn1_write_value (asn1_struct, tmp, "NEW", 1);
      if (result != ASN1_SUCCESS)
	{
	  gnutls_assert ();
	  return _gnutls_asn2err (result);
	}

      _gnutls_str_cat (tmp, sizeof (tmp), ".?LAST");

    }

  result = _gnutls_x509_der_encode_and_copy (c2, "", asn1_struct, tmp, 0);
  if (result < 0)
    {
      gnutls_assert ();
      return result;
    }

  /* write the type
   */
  _gnutls_str_cpy (tmp, sizeof (tmp), where);
  _gnutls_str_cat (tmp, sizeof (tmp), ".type");

  result = asn1_write_value (asn1_struct, tmp, given_oid, 1);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      return _gnutls_asn2err (result);
    }

  return 0;
}
Example #18
0
int
_gnutls_x509_crq_set_extension(gnutls_x509_crq_t crq,
                               const char *ext_id,
                               const gnutls_datum_t * ext_data,
                               unsigned int critical)
{
    unsigned char *extensions = NULL;
    size_t extensions_size = 0;
    gnutls_datum_t der;
    ASN1_TYPE c2;
    int result;

    result =
        gnutls_x509_crq_get_attribute_by_oid(crq,
                "1.2.840.113549.1.9.14",
                0, NULL,
                &extensions_size);
    if (result == GNUTLS_E_SHORT_MEMORY_BUFFER) {
        extensions = gnutls_malloc(extensions_size);
        if (extensions == NULL) {
            gnutls_assert();
            return GNUTLS_E_MEMORY_ERROR;
        }

        result = gnutls_x509_crq_get_attribute_by_oid(crq,
                 "1.2.840.113549.1.9.14",
                 0,
                 extensions,
                 &extensions_size);
    }
    if (result < 0) {
        if (result == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
            extensions_size = 0;
        } else {
            gnutls_assert();
            gnutls_free(extensions);
            return result;
        }
    }

    result =
        asn1_create_element(_gnutls_get_pkix(), "PKIX1.Extensions",
                            &c2);
    if (result != ASN1_SUCCESS) {
        gnutls_assert();
        gnutls_free(extensions);
        return _gnutls_asn2err(result);
    }

    if (extensions_size > 0) {
        result =
            asn1_der_decoding(&c2, extensions, extensions_size,
                              NULL);
        gnutls_free(extensions);
        if (result != ASN1_SUCCESS) {
            gnutls_assert();
            asn1_delete_structure(&c2);
            return _gnutls_asn2err(result);
        }
    }

    result = set_extension(c2, "", ext_id, ext_data, critical);
    if (result < 0) {
        gnutls_assert();
        asn1_delete_structure(&c2);
        return result;
    }

    result = _gnutls_x509_der_encode(c2, "", &der, 0);

    asn1_delete_structure(&c2);

    if (result < 0) {
        gnutls_assert();
        return result;
    }

    result =
        gnutls_x509_crq_set_attribute_by_oid(crq,
                "1.2.840.113549.1.9.14",
                der.data, der.size);
    gnutls_free(der.data);
    if (result < 0) {
        gnutls_assert();
        return result;
    }


    return 0;
}
Example #19
0
/* encodes the Dss-Sig-Value structure
 */
int
_gnutls_encode_ber_rs_raw(gnutls_datum_t * sig_value,
			  const gnutls_datum_t * r,
			  const gnutls_datum_t * s)
{
	ASN1_TYPE sig;
	int result, ret;
	uint8_t *tmp = NULL;

	if ((result =
	     asn1_create_element(_gnutls_get_gnutls_asn(),
				 "GNUTLS.DSASignatureValue",
				 &sig)) != ASN1_SUCCESS) {
		gnutls_assert();
		return _gnutls_asn2err(result);
	}

	if (s->data[0] >= 0x80 || r->data[0] >= 0x80) {
		tmp = gnutls_malloc(MAX(r->size, s->size)+1);
		if (tmp == NULL) {
			ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
			goto cleanup;
		}
	}

	if (r->data[0] >= 0x80) {
		tmp[0] = 0;
		memcpy(&tmp[1], r->data, r->size);
		result = asn1_write_value(sig, "r", tmp, 1+r->size);
	} else {
		result = asn1_write_value(sig, "r", r->data, r->size);
	}

	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		ret = _gnutls_asn2err(result);
		goto cleanup;
	}


	if (s->data[0] >= 0x80) {
		tmp[0] = 0;
		memcpy(&tmp[1], s->data, s->size);
		result = asn1_write_value(sig, "s", tmp, 1+s->size);
	} else {
		result = asn1_write_value(sig, "s", s->data, s->size);
	}

	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		ret = _gnutls_asn2err(result);
		goto cleanup;
	}

	ret = _gnutls_x509_der_encode(sig, "", sig_value, 0);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	ret = 0;
 cleanup:
	gnutls_free(tmp);
	asn1_delete_structure(&sig);
	return ret;
}
Example #20
0
/* Writes the value of the datum in the given ASN1_TYPE. If str is non
 * zero it encodes it as OCTET STRING.
 */
int
_gnutls_x509_write_value (ASN1_TYPE c, const char *root,
			  const gnutls_datum_t * data, int str)
{
  int result;
  int asize;
  ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
  gnutls_datum_t val;

  asize = data->size + 16;

  val.data = gnutls_malloc (asize);
  if (val.data == NULL)
    {
      gnutls_assert ();
      result = GNUTLS_E_MEMORY_ERROR;
      goto cleanup;
    }

  if (str)
    {
      /* Convert it to OCTET STRING
       */
      if ((result = asn1_create_element
	   (_gnutls_get_pkix (), "PKIX1.pkcs-7-Data", &c2)) != ASN1_SUCCESS)
	{
	  gnutls_assert ();
	  result = _gnutls_asn2err (result);
	  goto cleanup;
	}

      result = asn1_write_value (c2, "", data->data, data->size);
      if (result != ASN1_SUCCESS)
	{
	  gnutls_assert ();
	  result = _gnutls_asn2err (result);
	  goto cleanup;
	}

      result = _gnutls_x509_der_encode (c2, "", &val, 0);
      if (result < 0)
	{
	  gnutls_assert ();
	  goto cleanup;
	}

    }
  else
    {
      val.data = data->data;
      val.size = data->size;
    }

  /* Write the data.
   */
  result = asn1_write_value (c, root, val.data, val.size);

  if (val.data != data->data)
    _gnutls_free_datum (&val);

  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      return _gnutls_asn2err (result);
    }

  return 0;

cleanup:
  if (val.data != data->data)
    _gnutls_free_datum (&val);
  return result;
}
Example #21
0
/**
 * gnutls_x509_crl_get_raw_issuer_dn:
 * @crl: should contain a gnutls_x509_crl_t structure
 * @dn: will hold the starting point of the DN
 *
 * This function will return a pointer to the DER encoded DN structure
 * and the length.
 *
 * Returns: a negative value on error, and zero on success.
 *
 * Since: 2.12.0
 **/
int
gnutls_x509_crl_get_raw_issuer_dn (gnutls_x509_crl_t crl,
				   gnutls_datum_t * dn)
{
  ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
  int result, len1;
  int start1, end1;
  gnutls_datum_t crl_signed_data;

  if (crl == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  /* get the issuer of 'crl'
   */
  if ((result =
       asn1_create_element (_gnutls_get_pkix (), "PKIX1.TBSCertList",
                            &c2)) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      return _gnutls_asn2err (result);
    }

  result =
    _gnutls_x509_get_signed_data (crl->crl, "tbsCertList", &crl_signed_data);
  if (result < 0)
    {
      gnutls_assert ();
      goto cleanup;
    }

  result =
    asn1_der_decoding (&c2, crl_signed_data.data, crl_signed_data.size, NULL);
  if (result != ASN1_SUCCESS)
    {
      /* couldn't decode DER */
      gnutls_assert ();
      asn1_delete_structure (&c2);
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  result =
    asn1_der_decoding_startEnd (c2, crl_signed_data.data,
                                crl_signed_data.size, "issuer",
                                &start1, &end1);

  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  len1 = end1 - start1 + 1;

  _gnutls_set_datum (dn, &crl_signed_data.data[start1], len1);

  result = 0;

cleanup:
  asn1_delete_structure (&c2);
  _gnutls_free_datum (&crl_signed_data);
  return result;
}
Example #22
0
/* This function will convert an attribute value, specified by the OID,
 * to a string. The result will be a null terminated string.
 *
 * res may be null. This will just return the res_size, needed to
 * hold the string.
 */
int
_gnutls_x509_oid_data2string (const char *oid, void *value,
			      int value_size, char *res, size_t * res_size)
{
  char str[MAX_STRING_LEN], tmpname[128];
  const char *ANAME = NULL;
  int CHOICE = -1, len = -1, result;
  ASN1_TYPE tmpasn = ASN1_TYPE_EMPTY;

  if (value == NULL || value_size <= 0 || res_size == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  if (_gnutls_x509_oid_data_printable (oid) == 0)
    {
      gnutls_assert ();
      return GNUTLS_E_INTERNAL_ERROR;
    }

  ANAME = asn1_find_structure_from_oid (_gnutls_get_pkix (), oid);
  CHOICE = _gnutls_x509_oid_data_choice (oid);

  if (ANAME == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_INTERNAL_ERROR;
    }

  _gnutls_str_cpy (str, sizeof (str), "PKIX1.");
  _gnutls_str_cat (str, sizeof (str), ANAME);

  if ((result =
       asn1_create_element (_gnutls_get_pkix (), str,
			    &tmpasn)) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      return _gnutls_asn2err (result);
    }

  if ((result =
       asn1_der_decoding (&tmpasn, value, value_size, NULL)) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      asn1_delete_structure (&tmpasn);
      return _gnutls_asn2err (result);
    }

  /* If this is a choice then we read the choice. Otherwise it
   * is the value;
   */
  len = sizeof (str) - 1;
  if ((result = asn1_read_value (tmpasn, "", str, &len)) != ASN1_SUCCESS)
    {				/* CHOICE */
      gnutls_assert ();
      asn1_delete_structure (&tmpasn);
      return _gnutls_asn2err (result);
    }

  if (CHOICE == 0)
    {
      str[len] = 0;

      if (res)
	_gnutls_str_cpy (res, *res_size, str);
      *res_size = len;

      asn1_delete_structure (&tmpasn);
    }
  else
    {				/* CHOICE */
      int non_printable = 0, teletex = 0;
      str[len] = 0;

      /* Note that we do not support strings other than
       * UTF-8 (thus ASCII as well).
       */
      if (strcmp (str, "printableString") != 0 &&
	  strcmp (str, "utf8String") != 0)
	{
	  non_printable = 1;
	}
      if (strcmp (str, "teletexString") == 0)
	teletex = 1;


      _gnutls_str_cpy (tmpname, sizeof (tmpname), str);

      len = sizeof (str) - 1;
      if ((result =
	   asn1_read_value (tmpasn, tmpname, str, &len)) != ASN1_SUCCESS)
	{
	  asn1_delete_structure (&tmpasn);
	  return _gnutls_asn2err (result);
	}

      asn1_delete_structure (&tmpasn);

      if (teletex != 0)
	{
	  int ascii = 0, i;
	  /* HACK: if the teletex string contains only ascii
	   * characters then treat it as printable.
	   */
	  for (i = 0; i < len; i++)
	    if (!isascii (str[i]))
	      ascii = 1;

	  if (ascii == 0)
	    non_printable = 0;
	}

      if (res)
	{
	  if (non_printable == 0)
	    {
	      str[len] = 0;
	      _gnutls_str_cpy (res, *res_size, str);
	      *res_size = len;
	    }
	  else
	    {
	      result = _gnutls_x509_data2hex (str, len, res, res_size);
	      if (result < 0)
		{
		  gnutls_assert ();
		  return result;
		}
	    }
	}

    }

  return 0;
}
Example #23
0
/* Converts a GOST key to
 * an internal structure (gnutls_private_key)
 */
static int
_privkey_decode_gost_key(const gnutls_datum_t * raw_key,
			 gnutls_x509_privkey_t pkey)
{
	int ret;
	int ecc_size = gnutls_ecc_curve_get_size(pkey->params.curve);

	/* Just to be sure here */
	if (ecc_size <= 0) {
		gnutls_assert();
		ret = GNUTLS_E_ECC_UNSUPPORTED_CURVE;
		goto error;
	}

	/* Private key form described in R 50.1.112-2016.
	 * Private key can come up as masked value concatenated with several masks.
	 * each part is of ecc_size bytes. Key will be unmasked in pk_fixup */
	if (raw_key->size % ecc_size == 0) {
		ret = _gnutls_mpi_init_scan_le(&pkey->params.params[GOST_K],
				raw_key->data, raw_key->size);
		if (ret < 0) {
			gnutls_assert();
			goto error;
		}
	} else if (raw_key->data[0] == ASN1_TAG_INTEGER) {
		ASN1_TYPE pkey_asn;

		/* Very old format: INTEGER packed in OCTET STRING */
		if ((ret = asn1_create_element(_gnutls_get_gnutls_asn(),
					       "GNUTLS.GOSTPrivateKeyOld",
					       &pkey_asn)) != ASN1_SUCCESS) {
			gnutls_assert();
			ret = _gnutls_asn2err(ret);
			goto error;
		}

		ret = _asn1_strict_der_decode(&pkey_asn,
				raw_key->data, raw_key->size,
				NULL);
		if (ret != ASN1_SUCCESS) {
			gnutls_assert();
			ret = _gnutls_asn2err(ret);
			asn1_delete_structure2(&pkey_asn, ASN1_DELETE_FLAG_ZEROIZE);
			goto error;
		}

		ret = _gnutls_x509_read_key_int(pkey_asn, "",
						&pkey->params.params[GOST_K]);
		if (ret < 0) {
			gnutls_assert();
			asn1_delete_structure2(&pkey_asn, ASN1_DELETE_FLAG_ZEROIZE);
			goto error;
		}
		asn1_delete_structure2(&pkey_asn, ASN1_DELETE_FLAG_ZEROIZE);
	} else if (raw_key->data[0] == ASN1_TAG_OCTET_STRING) {
		ASN1_TYPE pkey_asn;

		/* format: OCTET STRING packed in OCTET STRING */
		if ((ret = asn1_create_element(_gnutls_get_gnutls_asn(),
					       "GNUTLS.GOSTPrivateKey",
					       &pkey_asn)) != ASN1_SUCCESS) {
			gnutls_assert();
			ret = _gnutls_asn2err(ret);
			goto error;
		}

		ret = _asn1_strict_der_decode(&pkey_asn,
				raw_key->data, raw_key->size,
				NULL);
		if (ret != ASN1_SUCCESS) {
			gnutls_assert();
			ret = _gnutls_asn2err(ret);
			asn1_delete_structure2(&pkey_asn, ASN1_DELETE_FLAG_ZEROIZE);
			goto error;
		}

		ret = _gnutls_x509_read_key_int_le(pkey_asn, "",
						   &pkey->params.params[GOST_K]);
		if (ret < 0) {
			gnutls_assert();
			asn1_delete_structure2(&pkey_asn, ASN1_DELETE_FLAG_ZEROIZE);
			goto error;
		}
		asn1_delete_structure2(&pkey_asn, ASN1_DELETE_FLAG_ZEROIZE);
	} else {
		gnutls_assert();
		ret = GNUTLS_E_PARSING_ERROR;
		goto error;
	}

	pkey->params.params_nr++;

	return 0;

      error:
	return ret;

}
Example #24
0
/* DER Encodes the src ASN1_TYPE and stores it to
 * the given datum. If str is non null then the data are encoded as
 * an OCTET STRING.
 */
int
_gnutls_x509_der_encode (ASN1_TYPE src, const char *src_name,
			 gnutls_datum_t * res, int str)
{
  int size, result;
  int asize;
  opaque *data = NULL;
  ASN1_TYPE c2 = ASN1_TYPE_EMPTY;

  size = 0;
  result = asn1_der_coding (src, src_name, NULL, &size, NULL);
  if (result != ASN1_MEM_ERROR)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  /* allocate data for the der
   */

  if (str)
    size += 16;			/* for later to include the octet tags */
  asize = size;

  data = gnutls_malloc (size);
  if (data == NULL)
    {
      gnutls_assert ();
      result = GNUTLS_E_MEMORY_ERROR;
      goto cleanup;
    }

  result = asn1_der_coding (src, src_name, data, &size, NULL);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  if (str)
    {
      if ((result = asn1_create_element
	   (_gnutls_get_pkix (), "PKIX1.pkcs-7-Data", &c2)) != ASN1_SUCCESS)
	{
	  gnutls_assert ();
	  result = _gnutls_asn2err (result);
	  goto cleanup;
	}

      result = asn1_write_value (c2, "", data, size);
      if (result != ASN1_SUCCESS)
	{
	  gnutls_assert ();
	  result = _gnutls_asn2err (result);
	  goto cleanup;
	}

      result = asn1_der_coding (c2, "", data, &asize, NULL);
      if (result != ASN1_SUCCESS)
	{
	  gnutls_assert ();
	  result = _gnutls_asn2err (result);
	  goto cleanup;
	}

      size = asize;

      asn1_delete_structure (&c2);
    }

  res->data = data;
  res->size = size;
  return 0;

cleanup:
  gnutls_free (data);
  asn1_delete_structure (&c2);
  return result;

}
Example #25
0
/* 
 * Encodes a PKCS #1 private key to a PKCS #8 private key
 * info. The output will be allocated and stored into der. Also
 * the ASN1_TYPE of private key info will be returned.
 */
static int
encode_to_private_key_info(gnutls_x509_privkey_t pkey,
			   gnutls_datum_t * der, ASN1_TYPE * pkey_info)
{
	int result, len;
	uint8_t null = 0;
	const char *oid;
	gnutls_datum_t algo_params = { NULL, 0 };
	gnutls_datum_t algo_privkey = { NULL, 0 };

	oid = gnutls_pk_get_oid(pkey->params.algo);
	if (oid == NULL) {
		gnutls_assert();
		return GNUTLS_E_UNIMPLEMENTED_FEATURE;
	}

	result =
	    _gnutls_x509_write_pubkey_params(&pkey->params, &algo_params);
	if (result < 0) {
		gnutls_assert();
		return result;
	}

	if ((result =
	     asn1_create_element(_gnutls_get_pkix(),
				 "PKIX1.pkcs-8-PrivateKeyInfo",
				 pkey_info)) != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	/* Write the version.
	 */
	result = asn1_write_value(*pkey_info, "version", &null, 1);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	/* write the privateKeyAlgorithm
	 * fields. (OID+NULL data)
	 */
	result =
	    asn1_write_value(*pkey_info, "privateKeyAlgorithm.algorithm",
			     oid, 1);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	result =
	    asn1_write_value(*pkey_info, "privateKeyAlgorithm.parameters",
			     algo_params.data, algo_params.size);
	_gnutls_free_key_datum(&algo_params);

	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}


	/* Write the raw private key
	 */
	result = _encode_privkey(pkey, &algo_privkey);
	if (result < 0) {
		gnutls_assert();
		goto error;
	}

	result =
	    asn1_write_value(*pkey_info, "privateKey", algo_privkey.data,
			     algo_privkey.size);
	_gnutls_free_key_datum(&algo_privkey);

	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	if ((pkey->params.pkflags & GNUTLS_PK_FLAG_PROVABLE) && pkey->params.seed_size > 0) {
		gnutls_datum_t seed_info;
		/* rfc8479 attribute encoding */

		result = _x509_encode_provable_seed(pkey, &seed_info);
		if (result < 0) {
			gnutls_assert();
			goto error;
		}

		result = _x509_set_attribute(*pkey_info, "attributes", OID_ATTR_PROV_SEED, &seed_info);
		gnutls_free(seed_info.data);
		if (result < 0) {
			gnutls_assert();
			goto error;
		}
	} else {
		/* Append an empty Attributes field.
		 */
		result = asn1_write_value(*pkey_info, "attributes", NULL, 0);
		if (result != ASN1_SUCCESS) {
			gnutls_assert();
			result = _gnutls_asn2err(result);
			goto error;
		}
	}

	/* DER Encode the generated private key info.
	 */
	len = 0;
	result = asn1_der_coding(*pkey_info, "", NULL, &len, NULL);
	if (result != ASN1_MEM_ERROR) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	/* allocate data for the der
	 */
	der->size = len;
	der->data = gnutls_malloc(len);
	if (der->data == NULL) {
		gnutls_assert();
		return GNUTLS_E_MEMORY_ERROR;
	}

	result = asn1_der_coding(*pkey_info, "", der->data, &len, NULL);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	return 0;

      error:
	asn1_delete_structure2(pkey_info, ASN1_DELETE_FLAG_ZEROIZE);
	_gnutls_free_datum(&algo_params);
	_gnutls_free_key_datum(&algo_privkey);
	return result;

}
Example #26
0
static int      challenge(smb_session *s)
{
    char                  err_desc[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
    char                  resp_token[256];
    smb_message           msg;
    smb_session_xsec_resp *resp;
    smb_ntlmssp_challenge *challenge;
    ASN1_TYPE             token;
    int                   res, resp_token_size = 256;

    assert(s != NULL);

    if (smb_session_recv_msg(s, &msg) == 0)
    {
        BDSM_dbg("spnego challenge(): Unable to receive message\n");
        return DSM_ERROR_NETWORK;
    }

    if (msg.packet->header.status != NT_STATUS_MORE_PROCESSING_REQUIRED)
    {
        BDSM_dbg("spnego challenge(): Bad status (0x%x)\n",
                 msg.packet->header.status);
        return DSM_ERROR_GENERIC;
    }

    resp = (smb_session_xsec_resp *)msg.packet->payload;

    asn1_create_element(s->spnego_asn1, "SPNEGO.NegotiationToken", &token);
    res = asn1_der_decoding(&token, resp->payload, resp->xsec_blob_size,
                            err_desc);
    if (res != ASN1_SUCCESS)
    {
        asn1_delete_structure(&token);
        asn1_display_error("NegTokenResp parsing", res);
        BDSM_dbg("Parsing error detail: %s\n", err_desc);
        return DSM_ERROR_GENERIC;
    }

    // XXX Check the value of "negTokenResp.negResult"

    res = asn1_read_value(token, "negTokenResp.responseToken", resp_token,
                          &resp_token_size);
    asn1_delete_structure(&token);
    if (res != ASN1_SUCCESS)
    {
        asn1_display_error("NegTokenResp read responseToken", res);
        return DSM_ERROR_GENERIC;
    }

    // We got the server challenge, yeaaah.
    challenge = (smb_ntlmssp_challenge *)resp_token;
    if (smb_buffer_alloc(&s->xsec_target, challenge->tgt_len) == 0)
        return DSM_ERROR_GENERIC;
    memcpy(s->xsec_target.data,
           challenge->data + challenge->tgt_offset - sizeof(smb_ntlmssp_challenge),
           s->xsec_target.size);
    s->srv.challenge = challenge->challenge;
    s->srv.uid       = msg.packet->header.uid;

    BDSM_dbg("Server challenge is 0x%"PRIx64"\n", s->srv.challenge);

    return DSM_SUCCESS;
}
Example #27
0
/* Encodes a private key to the raw format PKCS #8 needs.
 * For RSA it is a PKCS #1 DER private key and for DSA it is
 * an ASN.1 INTEGER of the x value.
 */
inline static int
_encode_privkey(gnutls_x509_privkey_t pkey, gnutls_datum_t * raw)
{
	int ret;
	ASN1_TYPE spk = ASN1_TYPE_EMPTY;

	switch (pkey->params.algo) {
	case GNUTLS_PK_EDDSA_ED25519:
		/* we encode as octet string (which is going to be stored inside
		 * another octet string). No comments. */
		ret = _gnutls_x509_encode_string(ASN1_ETYPE_OCTET_STRING,
						 pkey->params.raw_priv.data, pkey->params.raw_priv.size,
						 raw);
		if (ret < 0)
			gnutls_assert();
		return ret;

	case GNUTLS_PK_GOST_01:
	case GNUTLS_PK_GOST_12_256:
	case GNUTLS_PK_GOST_12_512:
		if ((ret = asn1_create_element
					(_gnutls_get_gnutls_asn(), "GNUTLS.GOSTPrivateKey", &spk))
				!= ASN1_SUCCESS) {
			gnutls_assert();
			ret = _gnutls_asn2err(ret);
			goto error;
		}

		ret = _gnutls_x509_write_key_int_le(spk, "", pkey->params.params[GOST_K]);
		if (ret < 0) {
			gnutls_assert();
			goto error;
		}

		ret = _gnutls_x509_der_encode(spk, "", raw, 0);
		if (ret < 0) {
			gnutls_assert();
			goto error;
		}

		asn1_delete_structure2(&spk, ASN1_DELETE_FLAG_ZEROIZE);
		break;

	case GNUTLS_PK_RSA:
	case GNUTLS_PK_RSA_PSS:
	case GNUTLS_PK_ECDSA:
		ret =
		    _gnutls_x509_export_int2(pkey->key, GNUTLS_X509_FMT_DER,
					     "", raw);
		if (ret < 0) {
			gnutls_assert();
			goto error;
		}

		break;
	case GNUTLS_PK_DSA:
		/* DSAPublicKey == INTEGER */
		if ((ret = asn1_create_element
		     (_gnutls_get_gnutls_asn(), "GNUTLS.DSAPublicKey",
		      &spk))
		    != ASN1_SUCCESS) {
			gnutls_assert();
			return _gnutls_asn2err(ret);
		}

		ret =
		    _gnutls_x509_write_int(spk, "", pkey->params.params[4],
					   1);
		if (ret < 0) {
			gnutls_assert();
			goto error;
		}
		ret = _gnutls_x509_der_encode(spk, "", raw, 0);
		if (ret < 0) {
			gnutls_assert();
			goto error;
		}

		asn1_delete_structure2(&spk, ASN1_DELETE_FLAG_ZEROIZE);
		break;

	default:
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

	return 0;

      error:
	asn1_delete_structure2(&spk, ASN1_DELETE_FLAG_ZEROIZE);
	asn1_delete_structure(&spk);
	return ret;

}
Example #28
0
static int      auth(smb_session *s, const char *domain, const char *user,
                     const char *password)
{
    smb_message           *msg = NULL, resp;
    smb_session_xsec_req  req;
    smb_buffer            ntlm;
    ASN1_TYPE             token;
    int                   res, der_size = 512;
    char                  der[512], err_desc[ASN1_MAX_ERROR_DESCRIPTION_SIZE];

    msg = smb_message_new(SMB_CMD_SETUP);
    if (!msg)
        return DSM_ERROR_GENERIC;

    // this struct will be set at the end when we know the payload size
    SMB_MSG_ADVANCE_PKT(msg, smb_session_xsec_req);

    asn1_create_element(s->spnego_asn1, "SPNEGO.NegotiationToken", &token);

    // Select a response message type
    res = asn1_write_value(token, "", "negTokenResp", 1);
    if (res != ASN1_SUCCESS) goto error;

    // Delete all optionnal field except 'ResponseToken'
    res = asn1_write_value(token, "negTokenResp.negResult", NULL, 0);
    if (res != ASN1_SUCCESS) goto error;
    res = asn1_write_value(token, "negTokenResp.supportedMech", NULL, 0);
    if (res != ASN1_SUCCESS) goto error;
    res = asn1_write_value(token, "negTokenResp.mechListMIC", NULL, 0);
    if (res != ASN1_SUCCESS) goto error;


    smb_ntlmssp_response(s->srv.challenge, s->srv.ts - 4200, domain, domain, user,
                         password, &s->xsec_target, &ntlm);
    res = asn1_write_value(token, "negTokenResp.responseToken", ntlm.data,
                           ntlm.size);
    smb_buffer_free(&ntlm);
    if (res != ASN1_SUCCESS) goto error;

    res = asn1_der_coding(token, "", der, &der_size, err_desc);
    if (res != ASN1_SUCCESS)
    {
        smb_message_destroy(msg);
        BDSM_dbg("Encoding error: %s", err_desc);
        return DSM_ERROR_GENERIC;
    }

    smb_message_append(msg, der, der_size);
    if (msg->cursor % 2)
        smb_message_put8(msg, 0);
    smb_message_put_utf16(msg, SMB_OS, strlen(SMB_OS));
    smb_message_put16(msg, 0);
    smb_message_put_utf16(msg, SMB_LANMAN, strlen(SMB_LANMAN));
    smb_message_put16(msg, 0);
    smb_message_put16(msg, 0); // Empty PDC name

    SMB_MSG_INIT_PKT_ANDX(req);
    req.wct              = 12;
    req.max_buffer       = SMB_SESSION_MAX_BUFFER;
    req.mpx_count        = 16; // XXX ?
    req.vc_count         = 1;
    req.caps             = s->srv.caps; // XXX caps & our_caps_mask
    req.session_key      = s->srv.session_key;
    req.xsec_blob_size = der_size;
    req.payload_size   = msg->cursor - sizeof(smb_session_xsec_req);
    SMB_MSG_INSERT_PKT(msg, 0, req);

    asn1_delete_structure(&token);

    if (!smb_session_send_msg(s, msg))
    {
        smb_message_destroy(msg);
        BDSM_dbg("Unable to send Session Setup AndX (NTLMSSP_AUTH) message\n");
        return DSM_ERROR_NETWORK;
    }
    smb_message_destroy(msg);

    if (smb_session_recv_msg(s, &resp) == 0)
        return DSM_ERROR_NETWORK;

    if (!smb_session_check_nt_status(s, &resp))
        return DSM_ERROR_NT;
    else
    {
        smb_session_xsec_resp *r = (smb_session_xsec_resp *)resp.packet->payload;
        if (r->action & 0x0001)
            s->guest = true;

        s->srv.uid  = resp.packet->header.uid;
        s->logged = true;

        return DSM_SUCCESS;
    }

error:
    asn1_display_error("smb_session_login auth()", res);
    smb_message_destroy(msg);
    return DSM_ERROR_GENERIC;
}
Example #29
0
int
_pkcs12_decode_crt_bag(gnutls_pkcs12_bag_type_t type,
		       const gnutls_datum_t * in, gnutls_datum_t * out)
{
	int ret;
	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;

	switch (type) {
	case GNUTLS_BAG_CERTIFICATE:
		if ((ret = asn1_create_element(_gnutls_get_pkix(),
					       "PKIX1.pkcs-12-CertBag",
					       &c2)) != ASN1_SUCCESS) {
			gnutls_assert();
			ret = _gnutls_asn2err(ret);
			goto cleanup;
		}

		ret = asn1_der_decoding(&c2, in->data, in->size, NULL);
		if (ret != ASN1_SUCCESS) {
			gnutls_assert();
			ret = _gnutls_asn2err(ret);
			goto cleanup;
		}

		ret =
		    _gnutls_x509_read_string(c2, "certValue", out,
					     ASN1_ETYPE_OCTET_STRING, 1);
		if (ret < 0) {
			gnutls_assert();
			goto cleanup;
		}
		break;

	case GNUTLS_BAG_CRL:
		if ((ret = asn1_create_element(_gnutls_get_pkix(),
					       "PKIX1.pkcs-12-CRLBag",
					       &c2)) != ASN1_SUCCESS) {
			gnutls_assert();
			ret = _gnutls_asn2err(ret);
			goto cleanup;
		}

		ret = asn1_der_decoding(&c2, in->data, in->size, NULL);
		if (ret != ASN1_SUCCESS) {
			gnutls_assert();
			ret = _gnutls_asn2err(ret);
			goto cleanup;
		}

		ret =
		    _gnutls_x509_read_string(c2, "crlValue", out,
					     ASN1_ETYPE_OCTET_STRING, 1);
		if (ret < 0) {
			gnutls_assert();
			goto cleanup;
		}
		break;

	case GNUTLS_BAG_SECRET:
		if ((ret = asn1_create_element(_gnutls_get_pkix(),
					       "PKIX1.pkcs-12-SecretBag",
					       &c2)) != ASN1_SUCCESS) {
			gnutls_assert();
			ret = _gnutls_asn2err(ret);
			goto cleanup;
		}

		ret = asn1_der_decoding(&c2, in->data, in->size, NULL);
		if (ret != ASN1_SUCCESS) {
			gnutls_assert();
			ret = _gnutls_asn2err(ret);
			goto cleanup;
		}

		ret =
		    _gnutls_x509_read_string(c2, "secretValue", out,
					     ASN1_ETYPE_OCTET_STRING, 1);
		if (ret < 0) {
			gnutls_assert();
			goto cleanup;
		}
		break;

	default:
		gnutls_assert();
		asn1_delete_structure(&c2);
		return GNUTLS_E_UNIMPLEMENTED_FEATURE;
	}

	asn1_delete_structure(&c2);

	return 0;


      cleanup:

	asn1_delete_structure(&c2);
	return ret;
}
Example #30
0
File: pkcs7.c Project: ares89/vlc
/* Creates an empty signed data structure in the pkcs7
 * structure and returns a handle to the signed data.
 */
static int
create_empty_signed_data (ASN1_TYPE pkcs7, ASN1_TYPE * sdata)
{
  uint8_t one = 1;
  int result;

  *sdata = ASN1_TYPE_EMPTY;

  if ((result = asn1_create_element
       (_gnutls_get_pkix (), "PKIX1.pkcs-7-SignedData",
        sdata)) != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  /* Use version 1
   */
  result = asn1_write_value (*sdata, "version", &one, 1);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  /* Use no digest algorithms
   */

  /* id-data */
  result =
    asn1_write_value (*sdata, "encapContentInfo.eContentType",
                      "1.2.840.113549.1.7.5", 1);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  result = asn1_write_value (*sdata, "encapContentInfo.eContent", NULL, 0);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  /* Add no certificates.
   */

  /* Add no crls.
   */

  /* Add no signerInfos.
   */

  /* Write the content type of the signed data
   */
  result = asn1_write_value (pkcs7, "contentType", SIGNED_DATA_OID, 1);
  if (result != ASN1_SUCCESS)
    {
      gnutls_assert ();
      result = _gnutls_asn2err (result);
      goto cleanup;
    }

  return 0;

cleanup:
  asn1_delete_structure (sdata);
  return result;

}