// 削除ペイロードの構築 SE_BUF *SeIkeBuildDeletePayload(SE_IKE_PACKET_DELETE_PAYLOAD *t) { SE_IKE_DELETE_HEADER h; SE_BUF *ret; UINT i; // 引数チェック if (t == NULL) { return NULL; } SeZero(&h, sizeof(h)); h.DoI = SeEndian32(SE_IKE_SA_DOI_IPSEC); h.NumSpis = SE_LIST_NUM(t->SpiList); h.ProtocolId = t->ProtocolId; if (SE_LIST_NUM(t->SpiList) >= 1) { SE_BUF *b = SE_LIST_DATA(t->SpiList, 0); h.SpiSize = b->Size; } ret = SeNewBuf(); SeWriteBuf(ret, &h, sizeof(h)); for (i = 0;i < SE_LIST_NUM(t->SpiList);i++) { SE_BUF *b = SE_LIST_DATA(t->SpiList, i); SeWriteBuf(ret, b->Buf, b->Size); } return ret; }
// プロポーザルペイロードの構築 SE_BUF *SeIkeBuildProposalPayload(SE_IKE_PACKET_PROPOSAL_PAYLOAD *t) { SE_IKE_PROPOSAL_HEADER h; SE_BUF *ret, *b; // 引数チェック if (t == NULL) { return NULL; } SeZero(&h, sizeof(h)); h.Number = t->Number; h.NumTransforms = SE_LIST_NUM(t->PayloadList); h.ProtocolId = t->ProtocolId; h.SpiSize = t->Spi->Size; ret = SeNewBuf(); SeWriteBuf(ret, &h, sizeof(h)); SeWriteBufBuf(ret, t->Spi); b = SeIkeBuildPayloadList(t->PayloadList); SeWriteBufBuf(ret, b); SeFreeBuf(b); return ret; }
// SA ペイロードの構築 SE_BUF *SeIkeBuildSaPayload(SE_IKE_PACKET_SA_PAYLOAD *t) { SE_IKE_SA_HEADER h; SE_BUF *ret; SE_BUF *b; // 引数チェック if (t == NULL) { return NULL; } SeZero(&h, sizeof(h)); h.DoI = SeEndian32(SE_IKE_SA_DOI_IPSEC); h.Situation = SeEndian32(SE_IKE_SA_SITUATION_IDENTITY); ret = SeNewBuf(); SeWriteBuf(ret, &h, sizeof(h)); b = SeIkeBuildPayloadList(t->PayloadList); SeWriteBufBuf(ret, b); SeFreeBuf(b); return ret; }
// ペイロードリストからビット列を構築 SE_BUF *SeIkeBuildPayloadList(SE_LIST *o) { SE_BUF *b; UINT i; // 引数チェック if (o == NULL) { return NULL; } b = SeNewBuf(); for (i = 0;i < SE_LIST_NUM(o);i++) { SE_IKE_PACKET_PAYLOAD *p = SE_LIST_DATA(o, i); SE_IKE_PACKET_PAYLOAD *next = NULL; SE_IKE_COMMON_HEADER h; SE_BUF *tmp; if (i < (SE_LIST_NUM(o) - 1)) { next = SE_LIST_DATA(o, i + 1); } SeZero(&h, sizeof(h)); if (next != NULL) { h.NextPayload = next->PayloadType; } else { h.NextPayload = SE_IKE_PAYLOAD_NONE; } tmp = SeIkeBuildPayload(p); if (tmp != NULL) { h.PayloadSize = SeEndian16(tmp->Size + (USHORT)sizeof(h)); SeWriteBuf(b, &h, sizeof(h)); SeWriteBuf(b, tmp->Buf, tmp->Size); SeFreeBuf(tmp); } } SeSeekBuf(b, 0, 0); return b; }
// 文字列をパスワードに変換 SE_BUF *SeIkeStrToPassword(char *str) { SE_BUF *b; // 引数チェック if (str == NULL) { return SeNewBuf(); } if (SeStartWith(str, "0x") == false) { // 文字列をそのまま使用 b = SeNewBuf(); SeWriteBuf(b, str, SeStrLen(str)); } else { // 16 進として解釈 b = SeStrToBin(str + 2); } return b; }
// データペイロードの構築 SE_BUF *SeIkeBuildDataPayload(SE_IKE_PACKET_DATA_PAYLOAD *t) { SE_BUF *b; // 引数チェック if (t == NULL) { return NULL; } b = SeNewBuf(); SeWriteBuf(b, t->Data->Buf, t->Data->Size); return b; }
// 証明書要求ペイロードの構築 SE_BUF *SeIkeBuildCertRequestPayload(SE_IKE_PACKET_CERT_REQUEST_PAYLOAD *t) { SE_IKE_CERT_REQUEST_HEADER h; SE_BUF *ret; // 引数チェック if (t == NULL) { return NULL; } SeZero(&h, sizeof(h)); h.CertType = t->CertType; ret = SeNewBuf(); SeWriteBuf(ret, &h, sizeof(h)); SeWriteBufBuf(ret, t->Data); return ret; }
// 通知ペイロードの構築 SE_BUF *SeIkeBuildNoticePayload(SE_IKE_PACKET_NOTICE_PAYLOAD *t) { SE_IKE_NOTICE_HEADER h; SE_BUF *ret; // 引数チェック if (t == NULL) { return NULL; } SeZero(&h, sizeof(h)); h.DoI = SeEndian32(SE_IKE_SA_DOI_IPSEC); h.MessageType = SeEndian16(t->MessageType); h.ProtocolId = t->ProtocolId; h.SpiSize = t->Spi->Size; ret = SeNewBuf(); SeWriteBuf(ret, &h, sizeof(h)); SeWriteBuf(ret, t->Spi->Buf, t->Spi->Size); return ret; }
// ID ペイロードの構築 SE_BUF *SeIkeBuildIdPayload(SE_IKE_PACKET_ID_PAYLOAD *t) { SE_IKE_ID_HEADER h; SE_BUF *ret; // 引数チェック if (t == NULL) { return NULL; } SeZero(&h, sizeof(h)); h.IdType = t->Type; h.Port = SeEndian16(t->Port); h.ProtocolId = t->ProtocolId; ret = SeNewBuf(); SeWriteBuf(ret, &h, sizeof(h)); SeWriteBufBuf(ret, t->IdData); return ret; }
// トランスフォーム値の構築 SE_BUF *SeIkeBuildTransformValue(SE_IKE_PACKET_TRANSFORM_VALUE *v) { SE_BUF *b; UCHAR af_bit, type; USHORT size_or_value; // 引数チェック if (v == NULL) { return NULL; } type = v->Type; if (v->Value >= 65536) { // 32 bit af_bit = 0; size_or_value = sizeof(UINT); } else { // 16 bit af_bit = 0x80; size_or_value = SeEndian16((USHORT)v->Value); } b = SeNewBuf(); SeWriteBuf(b, &af_bit, sizeof(af_bit)); SeWriteBuf(b, &type, sizeof(type)); SeWriteBuf(b, &size_or_value, sizeof(size_or_value)); if (af_bit == 0) { UINT value = SeEndian32(v->Value); SeWriteBuf(b, &value, sizeof(UINT)); } return b; }
// トランスフォームペイロードの構築 SE_BUF *SeIkeBuildTransformPayload(SE_IKE_PACKET_TRANSFORM_PAYLOAD *t) { SE_IKE_TRANSFORM_HEADER h; SE_BUF *ret, *b; // 引数チェック if (t == NULL) { return NULL; } SeZero(&h, sizeof(h)); h.Number = t->Number; h.TransformId = t->TransformId; ret = SeNewBuf(); SeWriteBuf(ret, &h, sizeof(h)); b = SeIkeBuildTransformValueList(t->ValueList); SeWriteBufBuf(ret, b); SeFreeBuf(b); return ret; }
// トランスフォーム値リストの構築 SE_BUF *SeIkeBuildTransformValueList(SE_LIST *o) { SE_BUF *b; UINT i; // 引数チェック if (o == NULL) { return NULL; } b = SeNewBuf(); for (i = 0;i < SE_LIST_NUM(o);i++) { SE_IKE_PACKET_TRANSFORM_VALUE *v = SE_LIST_DATA(o, i); SE_BUF *tmp = SeIkeBuildTransformValue(v); SeWriteBufBuf(b, tmp); SeFreeBuf(tmp); } return b; }
// データの読み込み SE_BUF *SeLoad(char *name) { SE_BUF *b; void *data; UINT data_size; // 引数チェック if (name == NULL) { return NULL; } if (SeSysLoadData(name, &data, &data_size) == false) { return NULL; } b = SeNewBuf(); SeWriteBuf(b, data, data_size); SeSeekBuf(b, 0, 0); SeSysFreeData(data); return b; }
// IKE パケットの構築 SE_BUF *SeIkeBuild(SE_IKE_PACKET *p, SE_IKE_CRYPTO_PARAM *cparam) { SE_IKE_HEADER h; SE_BUF *msg_buf; SE_BUF *ret; // 引数チェック if (p == NULL) { return NULL; } SeZero(&h, sizeof(h)); h.InitiatorCookie = p->InitiatorCookie; h.ResponderCookie = p->ResponderCookie; h.NextPayload = SeIkeGetFirstPayloadType(p->PayloadList); h.Version = SE_IKE_VERSION; h.ExchangeType = p->ExchangeType; h.Flag = (p->FlagEncrypted ? SE_IKE_HEADER_FLAG_ENCRYPTED : 0) | (p->FlagCommit ? SE_IKE_HEADER_FLAG_COMMIT : 0) | (p->FlagAuthOnly ? SE_IKE_HEADER_FLAG_AUTH_ONLY : 0); h.MessageId = SeEndian32(p->MessageId); msg_buf = SeIkeBuildPayloadList(p->PayloadList); if (p->DecryptedPayload != NULL) { SeFreeBuf(p->DecryptedPayload); } p->DecryptedPayload = SeCloneBuf(msg_buf); if (p->FlagEncrypted) { SE_BUF *b; // 暗号化 b = SeIkeEncryptWithPadding(msg_buf->Buf, msg_buf->Size, cparam); if (b == NULL) { SeError("ISAKMP: Packet Encrypt Failed"); SeFreeBuf(msg_buf); return NULL; } SeFreeBuf(msg_buf); msg_buf = b; } h.MessageSize = SeEndian32(msg_buf->Size + sizeof(h)); ret = SeNewBuf(); SeWriteBuf(ret, &h, sizeof(h)); SeWriteBufBuf(ret, msg_buf); SeFreeBuf(msg_buf); SeSeekBuf(ret, 0, 0); return ret; }
// 提供システムコール: RSA 署名操作 bool crypt_sys_rsa_sign (void *key_data, UINT key_size, void *data, UINT data_size, void *sign, UINT *sign_buf_size) { SE_BUF *ret_buf; SE_KEY *key; SE_BUF *key_file_buf; SE_BUF *tmp_buf; // 引数チェック if (key_data == NULL || data == NULL || data_size == 0 || sign == NULL || sign_buf_size == NULL) { return false; } // 秘密鍵データのコピー key_file_buf = SeNewBuf(); SeWriteBuf(key_file_buf, key_data, key_size); tmp_buf = SeMemToBuf(key_file_buf->Buf, key_file_buf->Size); SeFreeBuf(key_file_buf); key = SeBufToKey(tmp_buf, true, true, NULL); if (key == NULL) { key = SeBufToKey(tmp_buf, true, false, NULL); } if (key == NULL) { chelp_printf("crypt.c: Loading Key Failed.\n"); SeFreeBuf(tmp_buf); *sign_buf_size = 0; return false; } SeFreeBuf(tmp_buf); ret_buf = SeRsaSignWithPadding(data, data_size, key); if (ret_buf == NULL) { chelp_printf("crypt.c: SeRsaSignWithPadding() Failed.\n"); SeFreeKey(key); *sign_buf_size = 0; return false; } if (*sign_buf_size < ret_buf->Size) { chelp_printf("crypt.c: Not Enough Buffer Space.\n"); *sign_buf_size = ret_buf->Size; SeFreeBuf(ret_buf); SeFreeKey(key); *sign_buf_size = ret_buf->Size; return false; } *sign_buf_size = ret_buf->Size; SeCopy(sign, ret_buf->Buf, ret_buf->Size); SeFreeBuf(ret_buf); SeFreeKey(key); return true; }