IoObject *IoCertificate_attributes(IoCertificate *self, IoObject *locals, IoMessage *m) { IoObject *map = IoObject_new(IoObject_state(self)); const EVP_PKEY *pkey = X509_extract_key(X509(self)); int i; for(i = 0; i < EVP_PKEY_get_attr_count(pkey); i++) { IoList *list = IoList_new(IoObject_state(self)); X509_ATTRIBUTE *attr = EVP_PKEY_get_attr(pkey, i); const char *key = (const char *)OBJ_nid2ln(OBJ_obj2nid(X509_ATTRIBUTE_get0_object(attr))); int j; for(j = 0; j < X509_ATTRIBUTE_count(attr); j++) { ASN1_TYPE *attrType = X509_ATTRIBUTE_get0_type(attr, j); ASN1_OBJECT *attrData = X509_ATTRIBUTE_get0_data(attr, j, attrType->type, NULL); //consider switching on attrType instead; //really, that would be wiser, so that dates, //numbers, etc can be happy /* switch(attrType->type) { case V_ASN1_OCTET_STRING: ... */ int len = i2t_ASN1_OBJECT(NULL, 0, attrData); char *value = calloc(len, sizeof(char)); i2t_ASN1_OBJECT(value, len, attrData); IoList_rawAppend_(list, IoSeq_newWithCString_(IoObject_state(self), value)); } IoObject_setSlot_to_(map, IOSYMBOL(key), list); } return map; }
int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a) { char *tmp = NULL; size_t tlen = 256; int i = -1; if ((a == NULL) || (a->data == NULL)) return(BIO_write(bp, "NULL", 4)); if ((tmp = malloc(tlen)) == NULL) return -1; i = i2t_ASN1_OBJECT(tmp, tlen, a); if (i > (int)(tlen - 1)) { explicit_bzero(tmp, tlen); free(tmp); if ((tmp = malloc(i + 1)) == NULL) return -1; tlen = i + 1; i = i2t_ASN1_OBJECT(tmp, tlen, a); } if (i <= 0) i = BIO_write(bp, "<INVALID>", 9); else i = BIO_write(bp, tmp, i); explicit_bzero(tmp, tlen); free(tmp); return (i); }
int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a) { char buf[80], *p = buf; int i; if ((a == NULL) || (a->data == NULL)) return(BIO_write(bp,"NULL",4)); i=i2t_ASN1_OBJECT(buf,sizeof buf,a); if (i > (int)(sizeof(buf) - 1)) { p = OPENSSL_malloc(i + 1); if (!p) return -1; i2t_ASN1_OBJECT(p,i + 1,a); } if (i <= 0) { i = BIO_write(bp, "<INVALID>", 9); i += BIO_dump(bp, (const char *)a->data, a->length); return i; } BIO_write(bp,p,i); if (p != buf) OPENSSL_free(p); return(i); }
int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen, ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de) { EVP_PBE_CTL *pbetmp, pbelu; int i; pbelu.pbe_nid = OBJ_obj2nid(pbe_obj); if (pbelu.pbe_nid != NID_undef) i = sk_find(pbe_algs, (char *)&pbelu); else i = -1; if (i == -1) { char obj_tmp[80]; EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_UNKNOWN_PBE_ALGORITHM); if (!pbe_obj) BUF_strlcpy (obj_tmp, "NULL", sizeof obj_tmp); else i2t_ASN1_OBJECT(obj_tmp, sizeof obj_tmp, pbe_obj); ERR_add_error_data(2, "TYPE=", obj_tmp); return 0; } if(!pass) passlen = 0; else if (passlen == -1) passlen = strlen(pass); pbetmp = (EVP_PBE_CTL *)sk_value (pbe_algs, i); i = (*pbetmp->keygen)(ctx, pass, passlen, param, pbetmp->cipher, pbetmp->md, en_de); if (!i) { EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_KEYGEN_FAILURE); return 0; } return 1; }
static int pbe_cipher_init(ASN1_OBJECT *pbe_obj, const uint8_t *pass_raw, size_t pass_raw_len, ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int is_encrypt) { const EVP_CIPHER *cipher; const EVP_MD *md; unsigned i; const struct pbe_suite *suite = NULL; const int pbe_nid = OBJ_obj2nid(pbe_obj); for (i = 0; i < sizeof(kBuiltinPBE) / sizeof(struct pbe_suite); i++) { if (kBuiltinPBE[i].pbe_nid == pbe_nid) { suite = &kBuiltinPBE[i]; break; } } if (suite == NULL) { char obj_str[80]; OPENSSL_PUT_ERROR(PKCS8, pbe_cipher_init, PKCS8_R_UNKNOWN_ALGORITHM); if (!pbe_obj) { strncpy(obj_str, "NULL", sizeof(obj_str)); } else { i2t_ASN1_OBJECT(obj_str, sizeof(obj_str), pbe_obj); } ERR_add_error_data(2, "TYPE=", obj_str); return 0; } if (suite->cipher_func == NULL) { cipher = NULL; } else { cipher = suite->cipher_func(); if (!cipher) { OPENSSL_PUT_ERROR(PKCS8, pbe_cipher_init, PKCS8_R_UNKNOWN_CIPHER); return 0; } } if (suite->md_func == NULL) { md = NULL; } else { md = suite->md_func(); if (!md) { OPENSSL_PUT_ERROR(PKCS8, pbe_cipher_init, PKCS8_R_UNKNOWN_DIGEST); return 0; } } if (!suite->keygen(ctx, pass_raw, pass_raw_len, param, cipher, md, is_encrypt)) { OPENSSL_PUT_ERROR(PKCS8, pbe_cipher_init, PKCS8_R_KEYGEN_FAILURE); return 0; } return 1; }
void cacert_X509_NAME_oneline(X509_NAME *a, s8 *p) { X509_NAME_ENTRY *ne; s32 i; s32 n,l1; const s8 *s; s8 tmp_buf[80]; s32 utf8len = 0; u8 mybuf[1024]; u8* myp=mybuf; s32 first = 0; if(a == NULL) { *p = '\0'; return; } for (i=0; i<sk_X509_NAME_ENTRY_num(a->entries); i++) { ne=sk_X509_NAME_ENTRY_value(a->entries,i); n=OBJ_obj2nid(ne->object); if ((n == NID_undef) || ((s=OBJ_nid2sn(n)) == NULL)) { i2t_ASN1_OBJECT(tmp_buf,sizeof(tmp_buf),ne->object); s=tmp_buf; } l1=strlen(s); utf8len = ASN1_STRING_to_UTF8(&myp,ne->value); if(utf8len < 0) { utf8len = 0; } if(first) { *(p++)=','; *(p++)=' '; } else { first = 1; } memcpy(p,s,(u32)l1); p+=l1; *(p++)='='; memcpy(p,myp,(u32)utf8len); p+=utf8len; } *p = '\0'; return; }
int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen, ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de) { const EVP_CIPHER *cipher; const EVP_MD *md; int cipher_nid, md_nid; EVP_PBE_KEYGEN *keygen; if (!EVP_PBE_find(EVP_PBE_TYPE_OUTER, OBJ_obj2nid(pbe_obj), &cipher_nid, &md_nid, &keygen)) { char obj_tmp[80]; EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_UNKNOWN_PBE_ALGORITHM); if (!pbe_obj) BUF_strlcpy (obj_tmp, "NULL", sizeof obj_tmp); else i2t_ASN1_OBJECT(obj_tmp, sizeof obj_tmp, pbe_obj); ERR_add_error_data(2, "TYPE=", obj_tmp); return 0; } if(!pass) passlen = 0; else if (passlen == -1) passlen = strlen(pass); if (cipher_nid == -1) cipher = NULL; else { cipher = EVP_get_cipherbynid(cipher_nid); if (!cipher) { EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_UNKNOWN_CIPHER); return 0; } } if (md_nid == -1) md = NULL; else { md = EVP_get_digestbynid(md_nid); if (!md) { EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_UNKNOWN_DIGEST); return 0; } } if (!keygen(ctx, pass, passlen, param, cipher, md, en_de)) { EVPerr(EVP_F_EVP_PBE_CIPHERINIT,EVP_R_KEYGEN_FAILURE); return 0; } return 1; }
int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a) { char buf[80]; int i; if ((a == NULL) || (a->data == NULL)) return(BIO_write(bp,"NULL",4)); i=i2t_ASN1_OBJECT(buf,80,a); if (i > 80) i=80; BIO_write(bp,buf,i); return(i); }
int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a) { char buf[80], *p = buf; int i; if ((a == NULL) || (a->data == NULL)) return(BIO_write(bp, "NULL",4)); i = i2t_ASN1_OBJECT(buf, sizeof buf, a); if (i > (int)(sizeof(buf) - 1)) { p = malloc(i + 1); if (!p) return -1; i2t_ASN1_OBJECT(p, i + 1, a); } if (i <= 0) return BIO_write(bp, "<INVALID>", 9); BIO_write(bp, p, i); if (p != buf) free(p); return (i); }
EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8) { EVP_PKEY *pkey = NULL; ASN1_OBJECT *algoid; char obj_tmp[80]; if (!PKCS8_pkey_get0(&algoid, NULL, NULL, NULL, p8)) return NULL; if (!(pkey = EVP_PKEY_new())) { EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE); return NULL; } if (!EVP_PKEY_set_type(pkey, OBJ_obj2nid(algoid))) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM); i2t_ASN1_OBJECT(obj_tmp, 80, algoid); ERR_add_error_data(2, "TYPE=", obj_tmp); goto error; } if (pkey->ameth->priv_decode) { if (!pkey->ameth->priv_decode(pkey, p8)) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_PRIVATE_KEY_DECODE_ERROR); goto error; } } else { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_METHOD_NOT_SUPPORTED); goto error; } return pkey; error: EVP_PKEY_free (pkey); return NULL; }
char *X509_NAME_oneline(X509_NAME *a, char *buf, int len) { X509_NAME_ENTRY *ne; int i; int n, lold, l, l1, l2, num, j, type; const char *s; char *p; unsigned char *q; BUF_MEM *b = NULL; static const char hex[17] = "0123456789ABCDEF"; int gs_doit[4]; char tmp_buf[80]; #ifdef CHARSET_EBCDIC unsigned char ebcdic_buf[1024]; #endif if (buf == NULL) { if ((b = BUF_MEM_new()) == NULL) goto err; if (!BUF_MEM_grow(b, 200)) goto err; b->data[0] = '\0'; len = 200; } else if (len == 0) { return NULL; } if (a == NULL) { if (b) { buf = b->data; OPENSSL_free(b); } strncpy(buf, "NO X509_NAME", len); buf[len - 1] = '\0'; return buf; } len--; /* space for '\0' */ l = 0; for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { ne = sk_X509_NAME_ENTRY_value(a->entries, i); n = OBJ_obj2nid(ne->object); if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) { i2t_ASN1_OBJECT(tmp_buf, sizeof(tmp_buf), ne->object); s = tmp_buf; } l1 = strlen(s); type = ne->value->type; num = ne->value->length; if (num > NAME_ONELINE_MAX) { X509err(X509_F_X509_NAME_ONELINE, X509_R_NAME_TOO_LONG); goto end; } q = ne->value->data; #ifdef CHARSET_EBCDIC if (type == V_ASN1_GENERALSTRING || type == V_ASN1_VISIBLESTRING || type == V_ASN1_PRINTABLESTRING || type == V_ASN1_TELETEXSTRING || type == V_ASN1_IA5STRING) { if (num > (int)sizeof(ebcdic_buf)) num = sizeof(ebcdic_buf); ascii2ebcdic(ebcdic_buf, q, num); q = ebcdic_buf; } #endif if ((type == V_ASN1_GENERALSTRING) && ((num % 4) == 0)) { gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 0; for (j = 0; j < num; j++) if (q[j] != 0) gs_doit[j & 3] = 1; if (gs_doit[0] | gs_doit[1] | gs_doit[2]) gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 1; else { gs_doit[0] = gs_doit[1] = gs_doit[2] = 0; gs_doit[3] = 1; } } else gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 1; for (l2 = j = 0; j < num; j++) { if (!gs_doit[j & 3]) continue; l2++; #ifndef CHARSET_EBCDIC if ((q[j] < ' ') || (q[j] > '~')) l2 += 3; #else if ((os_toascii[q[j]] < os_toascii[' ']) || (os_toascii[q[j]] > os_toascii['~'])) l2 += 3; #endif } lold = l; l += 1 + l1 + 1 + l2; if (l > NAME_ONELINE_MAX) { X509err(X509_F_X509_NAME_ONELINE, X509_R_NAME_TOO_LONG); goto end; } if (b != NULL) { if (!BUF_MEM_grow(b, l + 1)) goto err; p = &(b->data[lold]); } else if (l > len) { break; } else p = &(buf[lold]); *(p++) = '/'; memcpy(p, s, (unsigned int)l1); p += l1; *(p++) = '='; #ifndef CHARSET_EBCDIC /* q was assigned above already. */ q = ne->value->data; #endif for (j = 0; j < num; j++) { if (!gs_doit[j & 3]) continue; #ifndef CHARSET_EBCDIC n = q[j]; if ((n < ' ') || (n > '~')) { *(p++) = '\\'; *(p++) = 'x'; *(p++) = hex[(n >> 4) & 0x0f]; *(p++) = hex[n & 0x0f]; } else *(p++) = n; #else n = os_toascii[q[j]]; if ((n < os_toascii[' ']) || (n > os_toascii['~'])) { *(p++) = '\\'; *(p++) = 'x'; *(p++) = hex[(n >> 4) & 0x0f]; *(p++) = hex[n & 0x0f]; } else
EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8) { EVP_PKEY *pkey = NULL; #ifndef OPENSSL_NO_RSA RSA *rsa = NULL; #endif #ifndef OPENSSL_NO_DSA DSA *dsa = NULL; ASN1_TYPE *t1, *t2; ASN1_INTEGER *privkey; STACK_OF(ASN1_TYPE) *ndsa = NULL; #endif #ifndef OPENSSL_NO_EC EC_KEY *eckey = NULL; const unsigned char *p_tmp; #endif #if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_EC) ASN1_TYPE *param = NULL; BN_CTX *ctx = NULL; int plen; #endif X509_ALGOR *a; const unsigned char *p; const unsigned char *cp; int pkeylen; int nid; char obj_tmp[80]; if(p8->pkey->type == V_ASN1_OCTET_STRING) { p8->broken = PKCS8_OK; p = p8->pkey->value.octet_string->data; pkeylen = p8->pkey->value.octet_string->length; } else { p8->broken = PKCS8_NO_OCTET; p = p8->pkey->value.sequence->data; pkeylen = p8->pkey->value.sequence->length; } if (!(pkey = EVP_PKEY_new())) { EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE); return NULL; } a = p8->pkeyalg; nid = OBJ_obj2nid(a->algorithm); switch(nid) { #ifndef OPENSSL_NO_RSA case NID_rsaEncryption: cp = p; if (!(rsa = d2i_RSAPrivateKey (NULL,&cp, pkeylen))) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); return NULL; } EVP_PKEY_assign_RSA (pkey, rsa); break; #endif #ifndef OPENSSL_NO_DSA case NID_dsa: /* PKCS#8 DSA is weird: you just get a private key integer * and parameters in the AlgorithmIdentifier the pubkey must * be recalculated. */ /* Check for broken DSA PKCS#8, UGH! */ if(*p == (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED)) { if(!(ndsa = ASN1_seq_unpack_ASN1_TYPE(p, pkeylen, d2i_ASN1_TYPE, ASN1_TYPE_free))) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto dsaerr; } if(sk_ASN1_TYPE_num(ndsa) != 2 ) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto dsaerr; } /* Handle Two broken types: * SEQUENCE {parameters, priv_key} * SEQUENCE {pub_key, priv_key} */ t1 = sk_ASN1_TYPE_value(ndsa, 0); t2 = sk_ASN1_TYPE_value(ndsa, 1); if(t1->type == V_ASN1_SEQUENCE) { p8->broken = PKCS8_EMBEDDED_PARAM; param = t1; } else if(a->parameter->type == V_ASN1_SEQUENCE) { p8->broken = PKCS8_NS_DB; param = a->parameter; } else { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto dsaerr; } if(t2->type != V_ASN1_INTEGER) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto dsaerr; } privkey = t2->value.integer; } else { if (!(privkey=d2i_ASN1_INTEGER (NULL, &p, pkeylen))) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto dsaerr; } param = p8->pkeyalg->parameter; } if (!param || (param->type != V_ASN1_SEQUENCE)) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto dsaerr; } cp = p = param->value.sequence->data; plen = param->value.sequence->length; if (!(dsa = d2i_DSAparams (NULL, &cp, plen))) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto dsaerr; } /* We have parameters now set private key */ if (!(dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL))) { EVPerr(EVP_F_EVP_PKCS82PKEY,EVP_R_BN_DECODE_ERROR); goto dsaerr; } /* Calculate public key (ouch!) */ if (!(dsa->pub_key = BN_new())) { EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE); goto dsaerr; } if (!(ctx = BN_CTX_new())) { EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE); goto dsaerr; } if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) { EVPerr(EVP_F_EVP_PKCS82PKEY,EVP_R_BN_PUBKEY_ERROR); goto dsaerr; } EVP_PKEY_assign_DSA(pkey, dsa); BN_CTX_free (ctx); if(ndsa) sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); else ASN1_INTEGER_free(privkey); break; dsaerr: BN_CTX_free (ctx); sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); DSA_free(dsa); EVP_PKEY_free(pkey); return NULL; break; #endif #ifndef OPENSSL_NO_EC case NID_X9_62_id_ecPublicKey: p_tmp = p; /* extract the ec parameters */ param = p8->pkeyalg->parameter; if (!param || ((param->type != V_ASN1_SEQUENCE) && (param->type != V_ASN1_OBJECT))) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto ecerr; } if (param->type == V_ASN1_SEQUENCE) { cp = p = param->value.sequence->data; plen = param->value.sequence->length; if (!(eckey = d2i_ECParameters(NULL, &cp, plen))) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto ecerr; } } else { EC_GROUP *group; cp = p = param->value.object->data; plen = param->value.object->length; /* type == V_ASN1_OBJECT => the parameters are given * by an asn1 OID */ if ((eckey = EC_KEY_new()) == NULL) { EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_MALLOC_FAILURE); goto ecerr; } group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(a->parameter->value.object)); if (group == NULL) goto ecerr; EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); if (EC_KEY_set_group(eckey, group) == 0) goto ecerr; EC_GROUP_free(group); } /* We have parameters now set private key */ if (!d2i_ECPrivateKey(&eckey, &p_tmp, pkeylen)) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto ecerr; } /* calculate public key (if necessary) */ if (EC_KEY_get0_public_key(eckey) == NULL) { const BIGNUM *priv_key; const EC_GROUP *group; EC_POINT *pub_key; /* the public key was not included in the SEC1 private * key => calculate the public key */ group = EC_KEY_get0_group(eckey); pub_key = EC_POINT_new(group); if (pub_key == NULL) { EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB); goto ecerr; } if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) { EC_POINT_free(pub_key); EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB); goto ecerr; } priv_key = EC_KEY_get0_private_key(eckey); if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx)) { EC_POINT_free(pub_key); EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB); goto ecerr; } if (EC_KEY_set_public_key(eckey, pub_key) == 0) { EC_POINT_free(pub_key); EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB); goto ecerr; } EC_POINT_free(pub_key); } EVP_PKEY_assign_EC_KEY(pkey, eckey); if (ctx) BN_CTX_free(ctx); break; ecerr: if (ctx) BN_CTX_free(ctx); if (eckey) EC_KEY_free(eckey); if (pkey) EVP_PKEY_free(pkey); return NULL; #endif default: EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM); if (!a->algorithm) BUF_strlcpy (obj_tmp, "NULL", sizeof obj_tmp); else i2t_ASN1_OBJECT(obj_tmp, 80, a->algorithm); ERR_add_error_data(2, "TYPE=", obj_tmp); EVP_PKEY_free (pkey); return NULL; } return pkey; }
char *X509_NAME_oneline(X509_NAME *a, char *buf, int len) { X509_NAME_ENTRY *ne; size_t i; int n, lold, l, l1, l2, num, j, type; const char *s; char *p; unsigned char *q; BUF_MEM *b = NULL; static const char hex[17] = "0123456789ABCDEF"; int gs_doit[4]; char tmp_buf[80]; if (buf == NULL) { if ((b = BUF_MEM_new()) == NULL) goto err; if (!BUF_MEM_grow(b, 200)) goto err; b->data[0] = '\0'; len = 200; } else if (len <= 0) { return NULL; } if (a == NULL) { if (b) { buf = b->data; OPENSSL_free(b); } BUF_strlcpy(buf, "NO X509_NAME", len); return buf; } len--; /* space for '\0' */ l = 0; for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { ne = sk_X509_NAME_ENTRY_value(a->entries, i); n = OBJ_obj2nid(ne->object); if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) { i2t_ASN1_OBJECT(tmp_buf, sizeof(tmp_buf), ne->object); s = tmp_buf; } l1 = strlen(s); type = ne->value->type; num = ne->value->length; if (num > NAME_ONELINE_MAX) { OPENSSL_PUT_ERROR(X509, X509_R_NAME_TOO_LONG); goto end; } q = ne->value->data; if ((type == V_ASN1_GENERALSTRING) && ((num % 4) == 0)) { gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 0; for (j = 0; j < num; j++) if (q[j] != 0) gs_doit[j & 3] = 1; if (gs_doit[0] | gs_doit[1] | gs_doit[2]) gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 1; else { gs_doit[0] = gs_doit[1] = gs_doit[2] = 0; gs_doit[3] = 1; } } else gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 1; for (l2 = j = 0; j < num; j++) { if (!gs_doit[j & 3]) continue; l2++; if ((q[j] < ' ') || (q[j] > '~')) l2 += 3; } lold = l; l += 1 + l1 + 1 + l2; if (l > NAME_ONELINE_MAX) { OPENSSL_PUT_ERROR(X509, X509_R_NAME_TOO_LONG); goto end; } if (b != NULL) { if (!BUF_MEM_grow(b, l + 1)) goto err; p = &(b->data[lold]); } else if (l > len) { break; } else p = &(buf[lold]); *(p++) = '/'; OPENSSL_memcpy(p, s, (unsigned int)l1); p += l1; *(p++) = '='; q = ne->value->data; for (j = 0; j < num; j++) { if (!gs_doit[j & 3]) continue; n = q[j]; if ((n < ' ') || (n > '~')) { *(p++) = '\\'; *(p++) = 'x'; *(p++) = hex[(n >> 4) & 0x0f]; *(p++) = hex[n & 0x0f]; } else *(p++) = n; }
EVP_PKEY *EVP_PKCS82PKEY (PKCS8_PRIV_KEY_INFO *p8) { EVP_PKEY *pkey = NULL; #ifndef NO_RSA RSA *rsa = NULL; #endif #ifndef NO_DSA DSA *dsa = NULL; ASN1_INTEGER *privkey; ASN1_TYPE *t1, *t2, *param = NULL; STACK_OF(ASN1_TYPE) *ndsa = NULL; BN_CTX *ctx = NULL; int plen; #endif X509_ALGOR *a; unsigned char *p; int pkeylen; char obj_tmp[80]; if(p8->pkey->type == V_ASN1_OCTET_STRING) { p8->broken = PKCS8_OK; p = p8->pkey->value.octet_string->data; pkeylen = p8->pkey->value.octet_string->length; } else { p8->broken = PKCS8_NO_OCTET; p = p8->pkey->value.sequence->data; pkeylen = p8->pkey->value.sequence->length; } if (!(pkey = EVP_PKEY_new())) { EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE); return NULL; } a = p8->pkeyalg; switch (OBJ_obj2nid(a->algorithm)) { #ifndef NO_RSA case NID_rsaEncryption: if (!(rsa = d2i_RSAPrivateKey (NULL, &p, pkeylen))) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); return NULL; } EVP_PKEY_assign_RSA (pkey, rsa); break; #endif #ifndef NO_DSA case NID_dsa: /* PKCS#8 DSA is weird: you just get a private key integer * and parameters in the AlgorithmIdentifier the pubkey must * be recalculated. */ /* Check for broken DSA PKCS#8, UGH! */ if(*p == (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED)) { if(!(ndsa = ASN1_seq_unpack_ASN1_TYPE(p, pkeylen, d2i_ASN1_TYPE, ASN1_TYPE_free))) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto dsaerr; } if(sk_ASN1_TYPE_num(ndsa) != 2 ) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto dsaerr; } /* Handle Two broken types: * SEQUENCE {parameters, priv_key} * SEQUENCE {pub_key, priv_key} */ t1 = sk_ASN1_TYPE_value(ndsa, 0); t2 = sk_ASN1_TYPE_value(ndsa, 1); if(t1->type == V_ASN1_SEQUENCE) { p8->broken = PKCS8_EMBEDDED_PARAM; param = t1; } else if(a->parameter->type == V_ASN1_SEQUENCE) { p8->broken = PKCS8_NS_DB; param = a->parameter; } else { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto dsaerr; } if(t2->type != V_ASN1_INTEGER) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto dsaerr; } privkey = t2->value.integer; } else { if (!(privkey=d2i_ASN1_INTEGER (NULL, &p, pkeylen))) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto dsaerr; } param = p8->pkeyalg->parameter; } if (!param || (param->type != V_ASN1_SEQUENCE)) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto dsaerr; } p = param->value.sequence->data; plen = param->value.sequence->length; if (!(dsa = d2i_DSAparams (NULL, &p, plen))) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto dsaerr; } /* We have parameters now set private key */ if (!(dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL))) { EVPerr(EVP_F_EVP_PKCS82PKEY,EVP_R_BN_DECODE_ERROR); goto dsaerr; } /* Calculate public key (ouch!) */ if (!(dsa->pub_key = BN_new())) { EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE); goto dsaerr; } if (!(ctx = BN_CTX_new())) { EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE); goto dsaerr; } if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) { EVPerr(EVP_F_EVP_PKCS82PKEY,EVP_R_BN_PUBKEY_ERROR); goto dsaerr; } EVP_PKEY_assign_DSA(pkey, dsa); BN_CTX_free (ctx); if(ndsa) sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); else ASN1_INTEGER_free(privkey); break; dsaerr: BN_CTX_free (ctx); sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); DSA_free(dsa); EVP_PKEY_free(pkey); return NULL; break; #endif default: EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM); if (!a->algorithm) strcpy (obj_tmp, "NULL"); else i2t_ASN1_OBJECT(obj_tmp, 80, a->algorithm); ERR_add_error_data(2, "TYPE=", obj_tmp); EVP_PKEY_free (pkey); return NULL; } return pkey; }
//============================================================ // Initializes NotaryInfo object with data from OCSP object // pSigDoc - digidoc main object pointer // pNotary - NotaryInfo object to be initialized // resp - OCSP response object // notCert - Notary cert object // return error code //============================================================ int initializeNotaryInfoWithOCSP(SignedDoc *pSigDoc, NotaryInfo *pNotary, OCSP_RESPONSE *resp, X509 *notCert, int initDigest) { int n, err = ERR_OK; char buf[500]; OCSP_RESPBYTES *rb = NULL; OCSP_BASICRESP *br = NULL; OCSP_RESPDATA *rd = NULL; OCSP_RESPID *rid = NULL; // OCSP_CERTSTATUS *cst = NULL; OCSP_SINGLERESP *single = NULL; OCSP_CERTID *cid = NULL; X509_EXTENSION *nonce; //AM 26.09.08 DigiDocMemBuf mbuf1; mbuf1.pMem = 0; mbuf1.nLen = 0; RETURN_IF_NULL_PARAM(pNotary); RETURN_IF_NULL_PARAM(resp); // check the OCSP Response validity switch(OCSP_response_status(resp)) { case OCSP_RESPONSE_STATUS_SUCCESSFUL: // OK break; case OCSP_RESPONSE_STATUS_MALFORMEDREQUEST: SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_MALFORMED); case OCSP_RESPONSE_STATUS_INTERNALERROR: SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_INTERNALERR); case OCSP_RESPONSE_STATUS_TRYLATER: SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_TRYLATER); case OCSP_RESPONSE_STATUS_SIGREQUIRED: SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_SIGREQUIRED); case OCSP_RESPONSE_STATUS_UNAUTHORIZED: SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_UNAUTHORIZED); default: SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_UNSUCCESSFUL); } RETURN_IF_NULL_PARAM(resp->responseBytes);; rb = resp->responseBytes; if(OBJ_obj2nid(rb->responseType) != NID_id_pkix_OCSP_basic) SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_UNKNOWN_TYPE); if((br = OCSP_response_get1_basic(resp)) == NULL) SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_NO_BASIC_RESP); rd = br->tbsResponseData; if(ASN1_INTEGER_get(rd->version) != 0) SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_WRONG_VERSION); n = sk_OCSP_SINGLERESP_num(rd->responses); if(n != 1) SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_ONE_RESPONSE); single = sk_OCSP_SINGLERESP_value(rd->responses, 0); RETURN_IF_NULL(single); cid = single->certId; RETURN_IF_NULL(cid); ddocDebug(4, "initializeNotaryInfoWithOCSP", "CertStatus-type: %d", single->certStatus->type); //printf("TYPE: %d\n", single->certStatus->type); if(single->certStatus->type != 0) { ddocDebug(4, "initializeNotaryInfoWithOCSP", "errcode: %d", handleOCSPCertStatus(single->certStatus->type)); SET_LAST_ERROR_RETURN_CODE(handleOCSPCertStatus(single->certStatus->type)); } //Removed 31.10.2003 //if(single->singleExtensions) // SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_NO_SINGLE_EXT); if(!rd->responseExtensions || (sk_X509_EXTENSION_num(rd->responseExtensions) != 1) || ((nonce = sk_X509_EXTENSION_value(rd->responseExtensions, 0)) == NULL)) SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_NO_NONCE); i2t_ASN1_OBJECT(buf,sizeof(buf),nonce->object); if(strcmp(buf, OCSP_NONCE_NAME)) SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_NO_NONCE); rid = rd->responderId; if(rid->type == V_OCSP_RESPID_NAME) { pNotary->nRespIdType = RESPID_NAME_TYPE; } else if(rid->type == V_OCSP_RESPID_KEY) { pNotary->nRespIdType = RESPID_KEY_TYPE; } else { SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_WRONG_RESPID); } // producedAt err = asn1time2str(pSigDoc, rd->producedAt, buf, sizeof(buf)); setString(&(pNotary->timeProduced), buf, -1); n = sizeof(buf); if(rid->type == V_OCSP_RESPID_NAME) { //X509_NAME_oneline(rid->value.byName,buf,n); //AM 26.09.08 err = ddocCertGetDNFromName(rid->value.byName, &mbuf1); RETURN_IF_NOT(err == ERR_OK, err); err = ddocNotInfo_SetResponderId(pNotary, (char*)mbuf1.pMem, -1); ddocMemBuf_free(&mbuf1); } if(rid->type == V_OCSP_RESPID_KEY) { err = ddocNotInfo_SetResponderId(pNotary, (const char*)rid->value.byKey->data, rid->value.byKey->length); } // digest type i2t_ASN1_OBJECT(buf,sizeof(buf),cid->hashAlgorithm->algorithm); setString(&(pNotary->szDigestType), buf, -1); // signature algorithm i2t_ASN1_OBJECT(buf,sizeof(buf),br->signatureAlgorithm->algorithm); setString(&(pNotary->szSigType), buf, -1); // notary cert if(notCert && !err) err = addNotaryInfoCert(pSigDoc, pNotary, notCert); // save the response in memory err = ddocNotInfo_SetOCSPResponse_Value(pNotary, resp); // get the digest from original OCSP data if(initDigest && notCert) { err = calcNotaryDigest(pSigDoc, pNotary); } if(br != NULL) OCSP_BASICRESP_free(br); if (err != ERR_OK) SET_LAST_ERROR(err); return err; }
LiteralValue_Priv::LiteralValue_Priv(GENERAL_NAME *gen) : LiteralValue() { char oline[256], htmp[5]; unsigned char *p = NULL; int nid = 0; int i; ASN1_OBJECT *id_ms_san_upn; ASN1_OBJECT *id_pkinit_san; #define CREATE_OBJ_IF_NEEDED(oid, vn, sn, ln) \ nid = OBJ_txt2nid(oid); \ if (nid == NID_undef) { \ nid = OBJ_create(oid, sn, ln); \ if (nid == NID_undef) { \ LOGIT_ERROR("Error creating oid object for " << oid); \ return; \ } \ } \ vn = OBJ_nid2obj(nid); CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.2", id_pkinit_san, "id-pkinit-san", "KRB5PrincipalName"); CREATE_OBJ_IF_NEEDED("1.3.6.1.4.1.311.20.2.3", id_ms_san_upn, "id-ms-san-upn", "Microsoft Universal Principal Name"); switch (gen->type) { case GEN_EMAIL: setLiteral("email", asn1string2string(gen->d.ia5)); break; case GEN_DNS: setLiteral("DNS", asn1string2string(gen->d.ia5)); break; case GEN_URI: setLiteral("URI", asn1string2string(gen->d.ia5)); break; case GEN_DIRNAME: X509_NAME_oneline(gen->d.dirn, oline, 256); setLiteral("DirName", oline); break; case GEN_IPADD: p = gen->d.ip->data; /* BUG: doesn't support IPV6 */ if(gen->d.ip->length == 4) { BIO_snprintf(oline, sizeof oline, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]); } else if(gen->d.ip->length == 16) { oline[0] = 0; for (i = 0; i < 8; i++) { BIO_snprintf(htmp, sizeof htmp, "%X", p[0] << 8 | p[1]); p += 2; strcat(oline, htmp); if (i != 7) strcat(oline, ":"); } } else { LOGIT_ERROR("Invalid IP Address"); CA_MGM_THROW(ca_mgm::SyntaxException, "Invalid IP Address"); break; } setLiteral("IP", oline); break; case GEN_RID: i2t_ASN1_OBJECT(oline, 256, gen->d.rid); setLiteral("RID", oline); break; case GEN_OTHERNAME: // krb5PrincipalName || Microsoft Universal Principal Name if(OBJ_cmp(id_pkinit_san, gen->d.otherName->type_id) == 0) { decode_krb5_principal_name(gen->d.otherName->value->value.sequence->data, gen->d.otherName->value->value.sequence->length); } else if (OBJ_cmp(id_ms_san_upn, gen->d.otherName->type_id) == 0) { setLiteral("1.3.6.1.4.1.311.20.2.3", (char*)gen->d.otherName->value->value.sequence->data); } else { setLiteral("othername", std::string("unsupported(") + str::numstring(OBJ_obj2nid(gen->d.otherName->type_id)) + ")"); } break; case GEN_X400: setLiteral("X400Name", "unsupported"); break; case GEN_EDIPARTY: setLiteral("EdiPartyName", "unsupported"); break; } }