📄 secutil.c
字号:
goto loser; } return SECSuccess;loser: SECITEM_FreeItem(dst, PR_FALSE); return SECFailure;}SECStatusSECU_TextFileToItem(SECItem *dst, PRFileDesc *src){ PRFileInfo info; PRInt32 numBytes; PRStatus prStatus; unsigned char *buf; if (src == PR_STDIN) return secu_StdinToItem(dst); prStatus = PR_GetOpenFileInfo(src, &info); if (prStatus != PR_SUCCESS) { PORT_SetError(SEC_ERROR_IO); return SECFailure; } buf = (unsigned char*)PORT_Alloc(info.size); if (!buf) return SECFailure; numBytes = PR_Read(src, buf, info.size); if (numBytes != info.size) { PORT_SetError(SEC_ERROR_IO); goto loser; } if (buf[numBytes-1] == '\n') numBytes--;#ifdef _WINDOWS if (buf[numBytes-1] == '\r') numBytes--;#endif /* XXX workaround for 3.1, not all utils zero dst before sending */ dst->data = 0; if (!SECITEM_AllocItem(NULL, dst, numBytes)) goto loser; memcpy(dst->data, buf, numBytes); PORT_Free(buf); return SECSuccess;loser: PORT_Free(buf); return SECFailure;}SECStatusSECU_ReadDERFromFile(SECItem *der, PRFileDesc *inFile, PRBool ascii){ SECStatus rv; char *asc, *body, *trailer; if (ascii) { /* First convert ascii to binary */ SECItem filedata; /* Read in ascii data */ rv = SECU_FileToItem(&filedata, inFile); asc = filedata.data; if (!asc) { fprintf(stderr, "unable to read data from input file\n"); return SECFailure; } /* check for headers and trailers and remove them */ if ((body = strstr(asc, "-----BEGIN")) != NULL) { body = PORT_Strchr(body, '\n') + 1; trailer = strstr(body, "-----END"); if (trailer != NULL) { *trailer = '\0'; } else { fprintf(stderr, "input has header but no trailer\n"); return SECFailure; } } else { body = asc; } /* Convert to binary */ rv = ATOB_ConvertAsciiToItem(der, body); if (rv) { fprintf(stderr, "error converting ascii to binary (%s)\n", SECU_Strerror(PORT_GetError())); return SECFailure; } PORT_Free(asc); } else { /* Read in binary der */ rv = SECU_FileToItem(der, inFile); if (rv) { fprintf(stderr, "error converting der (%s)\n", SECU_Strerror(PORT_GetError())); return SECFailure; } } return SECSuccess;}#define INDENT_MULT 4voidSECU_Indent(FILE *out, int level){ int i; for (i = 0; i < level; i++) { fprintf(out, " "); }}static void secu_Newline(FILE *out){ fprintf(out, "\n");}voidSECU_PrintAsHex(FILE *out, SECItem *data, char *m, int level){ unsigned i; int column; if ( m ) { SECU_Indent(out, level); fprintf(out, "%s:\n", m); level++; } SECU_Indent(out, level); column = level*INDENT_MULT; for (i = 0; i < data->len; i++) { if (i != data->len - 1) { fprintf(out, "%02x:", data->data[i]); column += 4; } else { fprintf(out, "%02x", data->data[i]); column += 3; break; } if (column > 76) { secu_Newline(out); SECU_Indent(out, level); column = level*INDENT_MULT; } } level--; if (column != level*INDENT_MULT) { secu_Newline(out); }}voidSECU_PrintInteger(FILE *out, SECItem *i, char *m, int level){ int iv; if (i->len > 4) { SECU_PrintAsHex(out, i, m, level); } else { iv = DER_GetInteger(i); SECU_Indent(out, level); if (m) { fprintf(out, "%s: %d (0x%x)\n", m, iv, iv); } else { fprintf(out, "%d (0x%x)\n", iv, iv); } }}voidSECU_PrintString(FILE *out, SECItem *i, char *m, int level){ char *string; unsigned char *data = i->data; int len = i->len; int lenlen; int tag; string = PORT_ZAlloc(i->len+1); tag = *data++; len--; if (data[1] & 0x80) { lenlen = data[1] & 0x1f; } else { lenlen = 1; } data += lenlen; len -= lenlen; if (len <= 0) return; PORT_Memcpy(string,data,len); /* should check the validity of tag, and convert the string as necessary */ SECU_Indent(out, level); if (m) { fprintf(out, "%s: \"%s\"\n", m, string); } else { fprintf(out, "\"%s\"\n", string); }}static voidsecu_PrintBoolean(FILE *out, SECItem *i, char *m, int level){ int val = 0; if ( i->data ) { val = i->data[0]; } if (m) { SECU_Indent(out, level); fprintf(out, "%s:\n", m); level++; } if ( val ) { SECU_Indent(out, level); fprintf(out, "%s\n", "True"); } else { SECU_Indent(out, level); fprintf(out, "%s\n", "False"); } }/* * Format and print "time". If the tag message "m" is not NULL, * do indent formatting based on "level" and add a newline afterward; * otherwise just print the formatted time string only. */static voidsecu_PrintTime(FILE *out, int64 time, char *m, int level){ PRExplodedTime printableTime; char *timeString; /* Convert to local time */ PR_ExplodeTime(time, PR_GMTParameters, &printableTime); timeString = PORT_Alloc(100); if (timeString == NULL) return; if (m != NULL) { SECU_Indent(out, level); fprintf(out, "%s: ", m); } PR_FormatTime(timeString, 100, "%a %b %d %H:%M:%S %Y", &printableTime); fprintf(out, timeString); if (m != NULL) fprintf(out, "\n"); PORT_Free(timeString);}/* * Format and print the UTC Time "t". If the tag message "m" is not NULL, * do indent formatting based on "level" and add a newline afterward; * otherwise just print the formatted time string only. */voidSECU_PrintUTCTime(FILE *out, SECItem *t, char *m, int level){ int64 time; SECStatus rv; rv = DER_UTCTimeToTime(&time, t); if (rv != SECSuccess) return; secu_PrintTime(out, time, m, level);}/* * Format and print the Generalized Time "t". If the tag message "m" * is not NULL, * do indent formatting based on "level" and add a newline * afterward; otherwise just print the formatted time string only. */voidSECU_PrintGeneralizedTime(FILE *out, SECItem *t, char *m, int level){ int64 time; SECStatus rv; rv = DER_GeneralizedTimeToTime(&time, t); if (rv != SECSuccess) return; secu_PrintTime(out, time, m, level);}static void secu_PrintAny(FILE *out, SECItem *i, char *m, int level);voidSECU_PrintSet(FILE *out, SECItem *t, char *m, int level){ int type= t->data[0] & 0x1f; int start; unsigned char *bp; SECU_Indent(out, level); if (m) { fprintf(out, "%s: ", m); } fprintf(out,"%s {\n", type == SEC_ASN1_SET ? "Set" : "Sequence"); start = 2; if (t->data[1] & 0x80) { start = (t->data[1] & 0x7f) +1; } for (bp=&t->data[start]; bp < &t->data[t->len]; ) { SECItem tmp; unsigned int i,len,lenlen; if (bp[1] & 0x80) { lenlen = bp[1] & 0x1f; len = 0; for (i=0; i < lenlen; i++) { len = len * 255 + bp[2+i]; } } else { lenlen = 1; len = bp[1]; } tmp.len = len+lenlen+1; tmp.data = bp; bp += tmp.len; secu_PrintAny(out,&tmp,NULL,level+1); } SECU_Indent(out, level); fprintf(out, "}\n");}static voidsecu_PrintAny(FILE *out, SECItem *i, char *m, int level){ if ( i->len ) { switch (i->data[0] & 0x1f) { case SEC_ASN1_INTEGER: SECU_PrintInteger(out, i, m, level); break; case SEC_ASN1_OBJECT_ID: SECU_PrintObjectID(out, i, m, level); break; case SEC_ASN1_BOOLEAN: secu_PrintBoolean(out, i, m, level); break; case SEC_ASN1_UTF8_STRING: case SEC_ASN1_PRINTABLE_STRING: case SEC_ASN1_VISIBLE_STRING: case SEC_ASN1_BMP_STRING: case SEC_ASN1_IA5_STRING: case SEC_ASN1_T61_STRING: case SEC_ASN1_UNIVERSAL_STRING: SECU_PrintString(out, i, m, level); break; case SEC_ASN1_GENERALIZED_TIME: SECU_PrintGeneralizedTime(out, i, m, level); break; case SEC_ASN1_UTC_TIME: SECU_PrintUTCTime(out, i, m, level); break; case SEC_ASN1_NULL: SECU_Indent(out, level); fprintf(out, "%s: NULL\n", m); break; case SEC_ASN1_SET: case SEC_ASN1_SEQUENCE: SECU_PrintSet(out, i, m, level); break; default: SECU_PrintAsHex(out, i, m, level); break; } }}static intsecu_PrintValidity(FILE *out, CERTValidity *v, char *m, int level){ SECU_Indent(out, level); fprintf(out, "%s:\n", m); SECU_PrintUTCTime(out, &v->notBefore, "Not Before", level+1); SECU_PrintUTCTime(out, &v->notAfter, "Not After", level+1); return 0;}voidSECU_PrintObjectID(FILE *out, SECItem *oid, char *m, int level){ char *name; SECOidData *oiddata; oiddata = SECOID_FindOID(oid); if (oiddata == NULL) { SECU_PrintAsHex(out, oid, m, level); return; } name = oiddata->desc; SECU_Indent(out, level); if (m != NULL) fprintf(out, "%s: ", m); fprintf(out, "%s\n", name);}voidSECU_PrintAlgorithmID(FILE *out, SECAlgorithmID *a, char *m, int level){ SECU_PrintObjectID(out, &a->algorithm, m, level); if (a->parameters.len == 0 || (a->parameters.len == 2 && PORT_Memcmp(a->parameters.data, "\005\000", 2) == 0)) { /* No arguments or NULL argument */ } else { /* Print args to algorithm */ SECU_PrintAsHex(out, &a->parameters, "Args", level+1); }}static voidsecu_PrintAttribute(FILE *out, SEC_PKCS7Attribute *attr, char *m, int level){ SECItem *value; int i; char om[100]; if (m) { SECU_Indent(out, level); fprintf(out, "%s:\n", m); } /* * Should make this smarter; look at the type field and then decode * and print the value(s) appropriately! */ SECU_PrintObjectID(out, &(attr->type), "Type", level+1); if (attr->values != NULL) { i = 0; while ((value = attr->values[i++]) != NULL) { sprintf(om, "Value (%d)%s", i, attr->encoded ? " (encoded)" : ""); if (attr->encoded || attr->typeTag == NULL) { SECU_PrintAsHex(out, value, om, level+1); } else { switch (attr->typeTag->offset) { default: SECU_PrintAsHex(out, value, om, level+1); break; case SEC_OID_PKCS9_CONTENT_TYPE: SECU_PrintObjectID(out, value, om, level+1); break; case SEC_OID_PKCS9_SIGNING_TIME: SECU_PrintUTCTime(out, value, om, level+1); break; } } } }}static voidsecu_PrintRSAPublicKey(FILE *out, SECKEYPublicKey *pk, char *m, int level){#if 0 /* * um, yeah, that might be nice, but if you look at the callers * you will see that they do not *set* this, so this will not work! * Instead, somebody needs to fix the callers to be smarter about * public key stuff, if that is important. */ PORT_Assert(pk->keyType == rsaKey);#endif SECU_Indent(out, level); fprintf(out, "%s:\n", m); SECU_PrintInteger(out, &pk->u.rsa.modulus, "Modulus", level+1); SECU_PrintInteger(out, &pk->u.rsa.publicExponent, "Exponent", level+1);}static voidsecu_PrintDSAPublicKey(FILE *out, SECKEYPublicKey *pk, char *m, int level){ SECU_Indent(out, level); fprintf(out, "%s:\n", m); SECU_PrintInteger(out, &pk->u.dsa.params.prime, "Prime", level+1); SECU_PrintInteger(out, &pk->u.dsa.params.subPrime, "Subprime", level+1); SECU_PrintInteger(out, &pk->u.dsa.params.base, "Base", level+1); SECU_PrintInteger(out, &pk->u.dsa.publicValue, "PublicValue", level+1);}static intsecu_PrintSubjectPublicKeyInfo(FILE *out, PRArenaPool *arena, CERTSubjectPublicKeyInfo *i, char *msg, int level){ SECKEYPublicKey *pk; int rv; SECU_Indent(out, level); fprintf(out, "%s:\n", msg); SECU_PrintAlgorithmID(out, &i->algorithm, "Public Key Algorithm", level+1); pk = (SECKEYPublicKey*) PORT_ZAlloc(sizeof(SECKEYPublicKey)); if (!pk) return PORT_GetError(); DER_ConvertBitString(&i->subjectPublicKey); switch(SECOID_FindOIDTag(&i->algorithm.algorithm)) { case SEC_OID_PKCS1_RSA_ENCRYPTION: rv = SEC_ASN1DecodeItem(arena, pk, SECKEY_RSAPublicKeyTemplate, &i->subjectPublicKey); if (rv) return rv; secu_PrintRSAPublicKey(out, pk, "RSA Public Key", level +1); break; case SEC_OID_ANSIX9_DSA_SIGNATURE: rv = SEC_ASN1DecodeItem(arena, pk, SECKEY_DSAPublicKeyTemplate, &i->subjectPublicKey); if (rv) return rv; secu_PrintDSAPublicKey(out, pk, "DSA Public Key", level +1); break; default: fprintf(out, "bad SPKI algorithm type\n"); return 0; } return 0;}static SECStatussecu_PrintX509InvalidDate(FILE *out, SECItem *value, char *msg, int level)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -