ASN1_STRING *ASN1_pack_string(void *obj, i2d_of_void *i2d, ASN1_STRING **oct) { unsigned char *p; ASN1_STRING *octmp; if (!oct || !*oct) { if (!(octmp = ASN1_STRING_new ())) { ASN1err(ASN1_F_ASN1_PACK_STRING,ERR_R_MALLOC_FAILURE); return NULL; } if (oct) *oct = octmp; } else octmp = *oct; if (!(octmp->length = i2d(obj, NULL))) { ASN1err(ASN1_F_ASN1_PACK_STRING,ASN1_R_ENCODE_ERROR); goto err; } if (!(p = OPENSSL_malloc (octmp->length))) { ASN1err(ASN1_F_ASN1_PACK_STRING,ERR_R_MALLOC_FAILURE); goto err; } octmp->data = p; i2d (obj, &p); return octmp; err: if (!oct || !*oct) { ASN1_STRING_free(octmp); if (oct) *oct = NULL; } return NULL; }
void *ASN1_dup (i2d_of_void * i2d, d2i_of_void * d2i, void *x) { unsigned char *b, *p; const unsigned char *p2; int i; char *ret; if (x == NULL) return (NULL); i = i2d (x, NULL); b = OPENSSL_malloc (i + 10); if (b == NULL) { ASN1err (ASN1_F_ASN1_DUP, ERR_R_MALLOC_FAILURE); return (NULL); } p = b; i = i2d (x, &p); p2 = b; ret = d2i (NULL, &p2, i); OPENSSL_free (b); return (ret); }
int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data, unsigned char *md, unsigned int *len) { int inl; unsigned char *str, *p; inl = i2d(data, NULL); if (inl <= 0) { ASN1err(ASN1_F_ASN1_DIGEST, ERR_R_INTERNAL_ERROR); return 0; } if ((str = OPENSSL_malloc(inl)) == NULL) { ASN1err(ASN1_F_ASN1_DIGEST, ERR_R_MALLOC_FAILURE); return 0; } p = str; i2d(data, &p); if (!EVP_Digest(str, inl, md, len, type, NULL)) { OPENSSL_free(str); return 0; } OPENSSL_free(str); return 1; }
// Full multiplication. // For every digit d in 'a' b is multiplied by d. // Final result is obtained by addition of all results of multiplications with proper offset. digit* multiply(const digit* a, const digit* b) { digit* result = 0; int offset = 0; while(a) { if(a->n != i2d(0)) { digit* row = copy(b); multiply_by_digit(row, d2i(a->n)); for(int i = 0; i < offset; ++i) { digit* new_row = new digit; new_row->next = row; new_row->n = i2d(0); row = new_row; } addto(row, result); deletebigint(row); } ++offset; a = a->next; } // needed when a or b is 0 rm_leading_0s(result); return result; }
int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, void *x) { char *b; unsigned char *p; int i, j = 0, n, ret = 1; n = i2d(x, NULL); if (n <= 0) return 0; b = (char *)OPENSSL_malloc(n); if (b == NULL) { OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); return (0); } p = (unsigned char *)b; i2d(x, &p); for (;;) { i = BIO_write(out, &(b[j]), n); if (i == n) break; if (i <= 0) { ret = 0; break; } j += i; n -= i; } OPENSSL_free(b); return (ret); }
int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, uint8_t *x) { char *b; uint8_t *p; int i, j = 0, n, ret = 1; n = i2d(x, NULL); b = malloc(n); if (b == NULL) { ASN1err(ASN1_F_ASN1_I2D_BIO, ERR_R_MALLOC_FAILURE); return (0); } p = (uint8_t *)b; i2d(x, &p); for (;;) { i = BIO_write(out, &(b[j]), n); if (i == n) break; if (i <= 0) { ret = 0; break; } j += i; n -= i; } free(b); return (ret); }
int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x) { char *b; unsigned char *p; int i, j = 0, n, ret = 1; n = i2d(x, NULL); if (n <= 0) return 0; b = OPENSSL_malloc(n); if (b == NULL) { ASN1err(ASN1_F_ASN1_I2D_BIO, ERR_R_MALLOC_FAILURE); return 0; } p = (unsigned char *)b; i2d(x, &p); for (;;) { i = BIO_write(out, &(b[j]), n); if (i == n) break; if (i <= 0) { ret = 0; break; } j += i; n -= i; } OPENSSL_free(b); return ret; }
int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey) { EVP_MD_CTX *ctx = EVP_MD_CTX_new(); const EVP_MD *type; unsigned char *p, *buf_in = NULL; int ret = -1, i, inl; if (ctx == NULL) { ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_MALLOC_FAILURE); goto err; } i = OBJ_obj2nid(a->algorithm); type = EVP_get_digestbyname(OBJ_nid2sn(i)); if (type == NULL) { ASN1err(ASN1_F_ASN1_VERIFY, ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM); goto err; } if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7) { ASN1err(ASN1_F_ASN1_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT); goto err; } inl = i2d(data, NULL); if (inl <= 0) { ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_INTERNAL_ERROR); goto err; } buf_in = OPENSSL_malloc((unsigned int)inl); if (buf_in == NULL) { ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_MALLOC_FAILURE); goto err; } p = buf_in; i2d(data, &p); ret = EVP_VerifyInit_ex(ctx, type, NULL) && EVP_VerifyUpdate(ctx, (unsigned char *)buf_in, inl); OPENSSL_clear_free(buf_in, (unsigned int)inl); if (!ret) { ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_EVP_LIB); goto err; } ret = -1; if (EVP_VerifyFinal(ctx, (unsigned char *)signature->data, (unsigned int)signature->length, pkey) <= 0) { ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_EVP_LIB); ret = 0; goto err; } ret = 1; err: EVP_MD_CTX_free(ctx); return ret; }
int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey) { EVP_MD_CTX ctx; const EVP_MD *type; unsigned char *p, *buf_in = NULL; int ret = -1, i, inl; EVP_MD_CTX_init(&ctx); i = OBJ_obj2nid(a->algorithm); type = EVP_get_digestbyname(OBJ_nid2sn(i)); if (type == NULL) { ASN1err(ASN1_F_ASN1_VERIFY, ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM); goto err; } if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7) { ASN1err(ASN1_F_ASN1_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT); goto err; } inl = i2d(data, NULL); buf_in = OPENSSL_malloc((unsigned int)inl); if (buf_in == NULL) { ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_MALLOC_FAILURE); goto err; } p = buf_in; i2d(data, &p); ret = EVP_VerifyInit_ex(&ctx, type, NULL) && EVP_VerifyUpdate(&ctx, (unsigned char *)buf_in, inl); OPENSSL_cleanse(buf_in, (unsigned int)inl); OPENSSL_free(buf_in); if (!ret) { ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_EVP_LIB); goto err; } ret = -1; if (EVP_VerifyFinal(&ctx, (unsigned char *)signature->data, (unsigned int)signature->length, pkey) <= 0) { ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_EVP_LIB); ret = 0; goto err; } /* * we don't need to zero the 'ctx' because we just checked public * information */ /* memset(&ctx,0,sizeof(ctx)); */ ret = 1; err: EVP_MD_CTX_cleanup(&ctx); return (ret); }
QByteArray i2d_bytearray(int(*i2d)(const void*, unsigned char **), const void *data) { QByteArray ba; ba.resize(i2d(data, NULL)); unsigned char *p = (unsigned char*)ba.data(); i2d(data, &p); openssl_error(); return ba; }
// Auxilary function for subtractfrom void rm_leading_0s(digit*& big) { digit* last_non_0 = 0; digit* big_iter = big; while(big_iter) { if(big_iter->n != i2d(0)) last_non_0 = big_iter; big_iter = big_iter->next; } if(last_non_0 == 0) { // no digits other then 0 big = 0; } else { if(last_non_0->next) { deletebigint(last_non_0->next); } last_non_0->next = 0; } }
bool pki_base::compare(pki_base *refcrl) { bool ret; ret = (i2d() == refcrl->i2d()); pki_openssl_error(); return ret; }
/* ======================================================================== */ void i2d_vec(double *d_vec,int *i_vec, int n) { int i; for(i=0;i<n;i++){ *(d_vec+i)= i2d(*(i_vec+i)); } }
int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data, unsigned char *md, unsigned int *len) { int i, ret; unsigned char *str, *p; i = i2d(data, NULL); if ((str = (unsigned char *)OPENSSL_malloc(i)) == NULL) { OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); return (0); } p = str; i2d(data, &p); ret = EVP_Digest(str, i, md, len, type, NULL); OPENSSL_free(str); return ret; }
// Auxilary function for multiply. // Performs one step of full multiplication. void multiply_by_digit(digit* a, int x) { digit* original_a = a; while(a) { a->n = i2d(d2i(a->n) * x); a = a->next; } fix_over_9(original_a); }
int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data, unsigned char *md, unsigned int *len) { int i; unsigned char *str,*p; i=i2d(data,NULL); if ((str=(unsigned char *)OPENSSL_malloc(i)) == NULL) { ASN1err(ASN1_F_ASN1_DIGEST,ERR_R_MALLOC_FAILURE); return(0); } p=str; i2d(data,&p); EVP_Digest(str, i, md, len, type, NULL); OPENSSL_free(str); return(1); }
char *ASN1_dup(int (*i2d)(), char *(*d2i)(), char *x) { unsigned char *b,*p; long i; char *ret; if (x == NULL) return(NULL); i=(long)i2d(x,NULL); b=(unsigned char *)OPENSSL_malloc((unsigned int)i+10); if (b == NULL) { ASN1err(ASN1_F_ASN1_DUP,ERR_R_MALLOC_FAILURE); return(NULL); } p= b; i=i2d(x,&p); p= b; ret=d2i(NULL,&p,i); OPENSSL_free(b); return(ret); }
QByteArray pki_evp::toData() { QByteArray ba; ba += db::intToData(key->type); ba += db::intToData(ownPass); ba += i2d(); ba += encKey; return ba; }
QByteArray pki_x509req::toData() { QByteArray ba; ba += i2d(); if (spki) { ba += i2d_spki(); } pki_openssl_error(); return ba; }
// Moves carry foreward. // This function is more general then fix_under_0 because // fix_over_9 is used in addition as well as in multiplication, // where temporarily excessive values can range up to 9*9 = 81 // with carry = 8 void fix_over_9(digit* big) { while(big) { if(d2i(big->n) > 9) { int carry = d2i(big->n) / 10; big->n = i2d(d2i(big->n) % 10); assert(carry > 0); if(big->next) big->next->n = i2d(d2i(big->next->n) + carry); else { big->next = new digit; big->next->next = 0; big->next->n = i2d(carry); } } big = big->next; } }
// Moves negative carry foreward void fix_under_0(digit* big) { while(big) { if(d2i(big->n) < 0) { big->n = i2d(10 + d2i(big->n)); assert(big->next); big->next->n--; } big = big->next; } }
// Subtraction is done in three steps; for first 2 see addto. // Third step is removing leading zeros. void subtractfrom(const digit* x, digit*& from) { digit* from_iter = from; while(x && from_iter) { from_iter->n = i2d(d2i(from_iter->n) - d2i(x->n)); x = x->next; from_iter = from_iter->next; } if(x) { from = 0; } else { fix_under_0(from); rm_leading_0s(from); } }
// Addition is done in two steps. // First one adds corresponding digits, where result of addition // can exceed 9. Second step moves carry foreward to obtain // digits in 0..9 void addto(const digit* from, digit*& to) { digit* to_iter = to; while(from && to_iter) { to_iter->n = i2d(d2i(to_iter->n) + d2i(from->n)); to_iter = to_iter->next; from = from->next; } // from is longer then to if(from) { // copy rest of 'from' to 'to' digit* rest_of_from = copy(from); append(to, rest_of_from); } fix_over_9(to); }
/** * Convert X to bytea */ bytea *pgx_X_to_bytea(const void *x, int(*i2d)(BIO *, const void *)) { BIO *bio = BIO_new(BIO_s_mem()); int len; bytea *result; char *ptr; int r; if ((r = i2d(bio, x)) != 1) { ereport(ERROR, (errcode(ERRCODE_DATA_CORRUPTED), errmsg("%s:%d: unable to retrieve data", __FILE__, __LINE__))); } if ((len = BIO_get_mem_data(bio, &ptr)) < 0) { elog(WARNING, "openssl error %d", ERR_get_error()); } result = (bytea *) palloc(len + 1 + VARHDRSZ); memcpy(VARDATA(result), ptr, len); SET_VARSIZE(result, len + VARHDRSZ); BIO_free(bio); return result; }
int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, char *x, const EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *callback, void *u) { EVP_CIPHER_CTX ctx; int dsize=0,i,j,ret=0; unsigned char *p,*data=NULL; const char *objstr=NULL; char buf[PEM_BUFSIZE]; unsigned char key[EVP_MAX_KEY_LENGTH]; unsigned char iv[EVP_MAX_IV_LENGTH]; if (enc != NULL) { objstr=OBJ_nid2sn(EVP_CIPHER_nid(enc)); if (objstr == NULL) { PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,PEM_R_UNSUPPORTED_CIPHER); goto err; } } if ((dsize=i2d(x,NULL)) < 0) { PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,ERR_R_ASN1_LIB); dsize=0; goto err; } /* dzise + 8 bytes are needed */ /* actually it needs the cipher block size extra... */ data=(unsigned char *)OPENSSL_malloc((unsigned int)dsize+20); if (data == NULL) { PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,ERR_R_MALLOC_FAILURE); goto err; } p=data; i=i2d(x,&p); if (enc != NULL) { if (kstr == NULL) { if (callback == NULL) klen=PEM_def_callback(buf,PEM_BUFSIZE,1,u); else klen=(*callback)(buf,PEM_BUFSIZE,1,u); if (klen <= 0) { PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,PEM_R_READ_KEY); goto err; } #ifdef CHARSET_EBCDIC /* Convert the pass phrase from EBCDIC */ ebcdic2ascii(buf, buf, klen); #endif kstr=(unsigned char *)buf; } RAND_add(data,i,0);/* put in the RSA key. */ OPENSSL_assert(enc->iv_len <= (int)sizeof(iv)); if (RAND_pseudo_bytes(iv,enc->iv_len) < 0) /* Generate a salt */ goto err; /* The 'iv' is used as the iv and as a salt. It is * NOT taken from the BytesToKey function */ EVP_BytesToKey(enc,EVP_md5(),iv,kstr,klen,1,key,NULL); if (kstr == (unsigned char *)buf) OPENSSL_cleanse(buf,PEM_BUFSIZE); OPENSSL_assert(strlen(objstr)+23+2*enc->iv_len+13 <= sizeof buf); buf[0]='\0'; PEM_proc_type(buf,PEM_TYPE_ENCRYPTED); PEM_dek_info(buf,objstr,enc->iv_len,(char *)iv); /* k=strlen(buf); */ EVP_CIPHER_CTX_init(&ctx); EVP_EncryptInit_ex(&ctx,enc,NULL,key,iv); EVP_EncryptUpdate(&ctx,data,&j,data,i); EVP_EncryptFinal_ex(&ctx,&(data[j]),&i); EVP_CIPHER_CTX_cleanup(&ctx); i+=j; ret=1; } else { ret=1; buf[0]='\0'; } i=PEM_write_bio(bp,name,buf,data,i); if (i <= 0) ret=0; err: OPENSSL_cleanse(key,sizeof(key)); OPENSSL_cleanse(iv,sizeof(iv)); OPENSSL_cleanse((char *)&ctx,sizeof(ctx)); OPENSSL_cleanse(buf,PEM_BUFSIZE); if (data != NULL) { OPENSSL_cleanse(data,(unsigned int)dsize); OPENSSL_free(data); } return(ret); }
int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, void *x, const EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *callback, void *u) { EVP_CIPHER_CTX *ctx = NULL; int dsize = 0, i = 0, j = 0, ret = 0; unsigned char *p, *data = NULL; const char *objstr = NULL; char buf[PEM_BUFSIZE]; unsigned char key[EVP_MAX_KEY_LENGTH]; unsigned char iv[EVP_MAX_IV_LENGTH]; if (enc != NULL) { objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc)); if (objstr == NULL || EVP_CIPHER_iv_length(enc) == 0 || EVP_CIPHER_iv_length(enc) > (int)sizeof(iv) /* * Check "Proc-Type: 4,Encrypted\nDEK-Info: objstr,hex-iv\n" * fits into buf */ || (strlen(objstr) + 23 + 2 * EVP_CIPHER_iv_length(enc) + 13) > sizeof(buf)) { PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, PEM_R_UNSUPPORTED_CIPHER); goto err; } } if ((dsize = i2d(x, NULL)) < 0) { PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, ERR_R_ASN1_LIB); dsize = 0; goto err; } /* dsize + 8 bytes are needed */ /* actually it needs the cipher block size extra... */ data = OPENSSL_malloc((unsigned int)dsize + 20); if (data == NULL) { PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, ERR_R_MALLOC_FAILURE); goto err; } p = data; i = i2d(x, &p); if (enc != NULL) { if (kstr == NULL) { if (callback == NULL) klen = PEM_def_callback(buf, PEM_BUFSIZE, 1, u); else klen = (*callback) (buf, PEM_BUFSIZE, 1, u); if (klen <= 0) { PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, PEM_R_READ_KEY); goto err; } #ifdef CHARSET_EBCDIC /* Convert the pass phrase from EBCDIC */ ebcdic2ascii(buf, buf, klen); #endif kstr = (unsigned char *)buf; } if (RAND_bytes(iv, EVP_CIPHER_iv_length(enc)) <= 0) /* Generate a salt */ goto err; /* * The 'iv' is used as the iv and as a salt. It is NOT taken from * the BytesToKey function */ if (!EVP_BytesToKey(enc, EVP_md5(), iv, kstr, klen, 1, key, NULL)) goto err; if (kstr == (unsigned char *)buf) OPENSSL_cleanse(buf, PEM_BUFSIZE); buf[0] = '\0'; PEM_proc_type(buf, PEM_TYPE_ENCRYPTED); PEM_dek_info(buf, objstr, EVP_CIPHER_iv_length(enc), (char *)iv); /* k=strlen(buf); */ ret = 1; if ((ctx = EVP_CIPHER_CTX_new()) == NULL || !EVP_EncryptInit_ex(ctx, enc, NULL, key, iv) || !EVP_EncryptUpdate(ctx, data, &j, data, i) || !EVP_EncryptFinal_ex(ctx, &(data[j]), &i)) ret = 0; if (ret == 0) goto err; i += j; } else { ret = 1; buf[0] = '\0'; } i = PEM_write_bio(bp, name, buf, data, i); if (i <= 0) ret = 0; err: OPENSSL_cleanse(key, sizeof(key)); OPENSSL_cleanse(iv, sizeof(iv)); EVP_CIPHER_CTX_free(ctx); OPENSSL_cleanse(buf, PEM_BUFSIZE); OPENSSL_clear_free(data, (unsigned int)dsize); return ret; }
/* int is_set: if TRUE, then sort the contents (i.e. it isn't a SEQUENCE) */ int i2d_ASN1_SET(STACK *a, unsigned char **pp, i2d_of_void *i2d, int ex_tag, int ex_class, int is_set) { int ret=0,r; int i; unsigned char *p; unsigned char *pStart, *pTempMem; MYBLOB *rgSetBlob; int totSize; if (a == NULL) return(0); for (i=sk_num(a)-1; i>=0; i--) ret+=i2d(sk_value(a,i),NULL); r=ASN1_object_size(1,ret,ex_tag); if (pp == NULL) return(r); p= *pp; ASN1_put_object(&p,1,ret,ex_tag,ex_class); /* Modified by [email protected] */ /* And then again by Ben */ /* And again by Steve */ if(!is_set || (sk_num(a) < 2)) { for (i=0; i<sk_num(a); i++) i2d(sk_value(a,i),&p); *pp=p; return(r); } pStart = p; /* Catch the beg of Setblobs*/ /* In this array we will store the SET blobs */ rgSetBlob = (MYBLOB *)OPENSSL_malloc(sk_num(a) * sizeof(MYBLOB)); if (rgSetBlob == NULL) { ASN1err(ASN1_F_I2D_ASN1_SET,ERR_R_MALLOC_FAILURE); return(0); } for (i=0; i<sk_num(a); i++) { rgSetBlob[i].pbData = p; /* catch each set encode blob */ i2d(sk_value(a,i),&p); rgSetBlob[i].cbData = (int)(p - rgSetBlob[i].pbData); /* Length of this SetBlob */ } *pp=p; totSize = (int)(p - pStart); /* This is the total size of all set blobs */ /* Now we have to sort the blobs. I am using a simple algo. *Sort ptrs *Copy to temp-mem *Copy from temp-mem to user-mem*/ qsort( rgSetBlob, sk_num(a), sizeof(MYBLOB), SetBlobCmp); if (!(pTempMem = OPENSSL_malloc(totSize))) { ASN1err(ASN1_F_I2D_ASN1_SET,ERR_R_MALLOC_FAILURE); return(0); } /* Copy to temp mem */ p = pTempMem; for(i=0; i<sk_num(a); ++i) { memcpy(p, rgSetBlob[i].pbData, rgSetBlob[i].cbData); p += rgSetBlob[i].cbData; } /* Copy back to user mem*/ memcpy(pStart, pTempMem, totSize); OPENSSL_free(pTempMem); OPENSSL_free(rgSetBlob); return(r); }
int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, X509_ALGOR *algor2, ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey, const EVP_MD *type) { EVP_MD_CTX ctx; unsigned char *p, *buf_in = NULL, *buf_out = NULL; int i, inl = 0, outl = 0, outll = 0; X509_ALGOR *a; EVP_MD_CTX_init(&ctx); for (i = 0; i < 2; i++) { if (i == 0) a = algor1; else a = algor2; if (a == NULL) continue; if (type->pkey_type == NID_dsaWithSHA1) { /* * special case: RFC 2459 tells us to omit 'parameters' with * id-dsa-with-sha1 */ ASN1_TYPE_free(a->parameter); a->parameter = NULL; } else if ((a->parameter == NULL) || (a->parameter->type != V_ASN1_NULL)) { ASN1_TYPE_free(a->parameter); if ((a->parameter = ASN1_TYPE_new()) == NULL) goto err; a->parameter->type = V_ASN1_NULL; } ASN1_OBJECT_free(a->algorithm); a->algorithm = OBJ_nid2obj(type->pkey_type); if (a->algorithm == NULL) { ASN1err(ASN1_F_ASN1_SIGN, ASN1_R_UNKNOWN_OBJECT_TYPE); goto err; } if (a->algorithm->length == 0) { ASN1err(ASN1_F_ASN1_SIGN, ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD); goto err; } } inl = i2d(data, NULL); buf_in = (unsigned char *)OPENSSL_malloc((unsigned int)inl); outll = outl = EVP_PKEY_size(pkey); buf_out = (unsigned char *)OPENSSL_malloc((unsigned int)outl); if ((buf_in == NULL) || (buf_out == NULL)) { outl = 0; ASN1err(ASN1_F_ASN1_SIGN, ERR_R_MALLOC_FAILURE); goto err; } p = buf_in; i2d(data, &p); if (!EVP_SignInit_ex(&ctx, type, NULL) || !EVP_SignUpdate(&ctx, (unsigned char *)buf_in, inl) || !EVP_SignFinal(&ctx, (unsigned char *)buf_out, (unsigned int *)&outl, pkey)) { outl = 0; ASN1err(ASN1_F_ASN1_SIGN, ERR_R_EVP_LIB); goto err; } if (signature->data != NULL) OPENSSL_free(signature->data); signature->data = buf_out; buf_out = NULL; signature->length = outl; /* * In the interests of compatibility, I'll make sure that the bit string * has a 'not-used bits' value of 0 */ signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); signature->flags |= ASN1_STRING_FLAG_BITS_LEFT; err: EVP_MD_CTX_cleanup(&ctx); if (buf_in != NULL) { OPENSSL_cleanse((char *)buf_in, (unsigned int)inl); OPENSSL_free(buf_in); } if (buf_out != NULL) { OPENSSL_cleanse((char *)buf_out, outll); OPENSSL_free(buf_out); } return (outl); }
std::pair<unsigned int, char> deconstruct(const unsigned int x) { return std::make_pair(x / 10, i2d(x % 10)); }
static int test_certs(BIO *fp) { int count; char *name = 0; char *header = 0; unsigned char *data = 0; long len; typedef X509 *(*d2i_X509_t)(X509 **, const unsigned char **, long); typedef int (*i2d_X509_t)(X509 *, unsigned char **); int err = 0; for (count = 0; !err && PEM_read_bio(fp, &name, &header, &data, &len); ++count) { int trusted = strcmp(name, PEM_STRING_X509_TRUSTED) == 0; d2i_X509_t d2i = trusted ? d2i_X509_AUX : d2i_X509; i2d_X509_t i2d = trusted ? i2d_X509_AUX : i2d_X509; X509 *cert = NULL; const unsigned char *p = data; unsigned char *buf = NULL; unsigned char *bufp; long enclen; if (!trusted && strcmp(name, PEM_STRING_X509) != 0 && strcmp(name, PEM_STRING_X509_OLD) != 0) { fprintf(stderr, "unexpected PEM object: %s\n", name); err = 1; goto next; } cert = d2i(NULL, &p, len); if (cert == NULL || (p - data) != len) { fprintf(stderr, "error parsing input %s\n", name); err = 1; goto next; } /* Test traditional 2-pass encoding into caller allocated buffer */ enclen = i2d(cert, NULL); if (len != enclen) { fprintf(stderr, "encoded length %ld of %s != input length %ld\n", enclen, name, len); err = 1; goto next; } if ((buf = bufp = OPENSSL_malloc(len)) == NULL) { perror("malloc"); err = 1; goto next; } enclen = i2d(cert, &bufp); if (len != enclen) { fprintf(stderr, "encoded length %ld of %s != input length %ld\n", enclen, name, len); err = 1; goto next; } enclen = (long) (bufp - buf); if (enclen != len) { fprintf(stderr, "unexpected buffer position after encoding %s\n", name); err = 1; goto next; } if (memcmp(buf, data, len) != 0) { fprintf(stderr, "encoded content of %s does not match input\n", name); err = 1; goto next; } OPENSSL_free(buf); buf = NULL; /* Test 1-pass encoding into library allocated buffer */ enclen = i2d(cert, &buf); if (len != enclen) { fprintf(stderr, "encoded length %ld of %s != input length %ld\n", enclen, name, len); err = 1; goto next; } if (memcmp(buf, data, len) != 0) { fprintf(stderr, "encoded content of %s does not match input\n", name); err = 1; goto next; } if (trusted) { /* Encode just the cert and compare with initial encoding */ OPENSSL_free(buf); buf = NULL; /* Test 1-pass encoding into library allocated buffer */ enclen = i2d(cert, &buf); if (enclen > len) { fprintf(stderr, "encoded length %ld of %s > input length %ld\n", enclen, name, len); err = 1; goto next; } if (memcmp(buf, data, enclen) != 0) { fprintf(stderr, "encoded cert content does not match input\n"); err = 1; goto next; } } /* * If any of these were null, PEM_read() would have failed. */ next: X509_free(cert); OPENSSL_free(buf); OPENSSL_free(name); OPENSSL_free(header); OPENSSL_free(data); } if (ERR_GET_REASON(ERR_peek_last_error()) == PEM_R_NO_START_LINE) { /* Reached end of PEM file */ if (count > 0) { ERR_clear_error(); return 1; } } /* Some other PEM read error */ print_errors(); return 0; }