piv_write_certificate(sc_card_t *card, const u8* buf, size_t count, unsigned long flags)
{
	piv_private_data_t * priv = PIV_DATA(card);
	int enumtag, tmplen, tmplen2, tmplen3;
	int r = SC_SUCCESS;
	u8 *sbuf = NULL;
	u8 *p;
	size_t sbuflen;
	size_t taglen;

	if ((tmplen = sc_asn1_put_tag(0x70, buf, count, NULL, 0, NULL)) <= 0 ||
	    (tmplen2 = sc_asn1_put_tag(0x71, NULL, 1, NULL, 0, NULL)) <= 0 ||
	    (tmplen3 = sc_asn1_put_tag(0xFE, NULL, 0, NULL, 0, NULL)) <= 0) {
		LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
	}

	taglen = tmplen + tmplen2 + tmplen3;
	tmplen = sc_asn1_put_tag(0x53, NULL, taglen, NULL, 0, NULL);
	if (tmplen <= 0) {
		LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
	}

	sbuflen = tmplen;
	sbuf = malloc(sbuflen);
	if (sbuf == NULL)
		LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
	p = sbuf;
	if ((r = sc_asn1_put_tag(0x53, NULL, taglen, sbuf, sbuflen, &p)) != SC_SUCCESS ||
	    (r = sc_asn1_put_tag(0x70, buf, count, p, sbuflen - (p - sbuf), &p)) != SC_SUCCESS ||
	    (r = sc_asn1_put_tag(0x71, NULL, 1, p, sbuflen - (p - sbuf), &p)) != SC_SUCCESS) {
		goto out;
	}
	/* Use 01 as per NIST 800-73-3 */
	*p++ = (flags) ? 0x01 : 0x00; /* certinfo, i.e. gzipped? */
	r = sc_asn1_put_tag(0xFE, NULL, 0, p, sbuflen - (p - sbuf), &p);
	if (r != SC_SUCCESS) {
		goto out;
	}

	enumtag = piv_objects[priv->selected_obj].enumtag;
	r = piv_put_data(card, enumtag, sbuf, sbuflen);

out:
	free(sbuf);
	LOG_FUNC_RETURN(card->ctx, r);
}
piv_write_certificate(sc_card_t *card, const u8* buf, size_t count, unsigned long flags)
{
	piv_private_data_t * priv = PIV_DATA(card);
	int enumtag, tmplen, tmplen2, tmplen3;
	int r = SC_SUCCESS;
	u8 *sbuf = NULL;
	u8 *p;
	size_t sbuflen;
	size_t taglen;

	if ((tmplen = sc_asn1_put_tag(0x70, buf, count, NULL, 0, NULL)) <= 0 ||
	    (tmplen2 = sc_asn1_put_tag(0x71, NULL, 1, NULL, 0, NULL)) <= 0 ||
	    (tmplen3 = sc_asn1_put_tag(0xFE, NULL, 0, NULL, 0, NULL)) <= 0) {
		LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
	}

	taglen = tmplen + tmplen2 + tmplen3;
	tmplen = sc_asn1_put_tag(0x53, NULL, taglen, NULL, 0, NULL);
	if (tmplen <= 0) {
		LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
	}

	sbuflen = tmplen;
	sbuf = malloc(sbuflen);
	if (sbuf == NULL)
		LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
	p = sbuf;
	if ((r = sc_asn1_put_tag(0x53, NULL, taglen, sbuf, sbuflen, &p)) != SC_SUCCESS ||
	    (r = sc_asn1_put_tag(0x70, buf, count, p, sbuflen - (p - sbuf), &p)) != SC_SUCCESS ||
	    (r = sc_asn1_put_tag(0x71, NULL, 1, p, sbuflen - (p - sbuf), &p)) != SC_SUCCESS) {
		goto out;
	}
	 
	*p++ = (flags) ? 0x01 : 0x00;  
	r = sc_asn1_put_tag(0xFE, NULL, 0, p, sbuflen - (p - sbuf), &p);
	if (r != SC_SUCCESS) {
		goto out;
	}

	enumtag = piv_objects[priv->selected_obj].enumtag;
	r = piv_put_data(card, enumtag, sbuf, sbuflen);

out:
	free(sbuf);
	LOG_FUNC_RETURN(card->ctx, r);
}